anon-identity
Version:
Decentralized identity framework with DIDs, Verifiable Credentials, and privacy-preserving selective disclosure
712 lines (693 loc) • 29.4 kB
JavaScript
;
/**
* LLM-Assisted Delegation Engine for MCP
*
* Intelligent delegation decision making using large language models
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.LLMDelegationEngine = void 0;
const events_1 = require("events");
const types_1 = require("../types");
const function_registry_1 = require("../functions/function-registry");
/**
* LLM Delegation Engine
*/
class LLMDelegationEngine extends events_1.EventEmitter {
constructor(messageRouter, authManager, auditLogger, config = {
defaultProvider: 'openai',
decisionTimeout: 30000,
requireHumanApproval: false,
minConfidenceThreshold: 0.7,
maxDelegationDepth: 5,
auditAllDecisions: true
}) {
super();
this.messageRouter = messageRouter;
this.authManager = authManager;
this.auditLogger = auditLogger;
this.config = config;
this.functionRegistry = new function_registry_1.FunctionRegistry();
this.initializeDelegationFunctions();
}
/**
* Make delegation decision using LLM
*/
async makeDelegationDecision(request, context) {
const sessionId = `delegation-${request.requestId}`;
try {
// Build comprehensive prompt for decision making
const prompt = this.buildDecisionPrompt(request, context);
// Define decision function
const decisionFunction = {
name: 'make_delegation_decision',
description: 'Make a comprehensive delegation decision with risk assessment',
parameters: {
type: 'object',
properties: {
decision: {
type: 'string',
description: 'The delegation decision',
enum: ['approve', 'deny', 'approve_with_modifications', 'request_more_info']
},
confidence: {
type: 'number',
description: 'Confidence level in the decision (0-1)',
minimum: 0,
maximum: 1
},
reasoning: {
type: 'string',
description: 'Detailed reasoning for the decision'
},
suggestedScopes: {
type: 'array',
description: 'Suggested scopes if different from requested',
items: { type: 'string' }
},
suggestedConstraints: {
type: 'object',
description: 'Additional constraints to apply'
},
suggestedDuration: {
type: 'number',
description: 'Suggested duration in milliseconds'
},
warnings: {
type: 'array',
description: 'Security warnings or concerns',
items: { type: 'string' }
},
riskLevel: {
type: 'string',
description: 'Overall risk level',
enum: ['low', 'medium', 'high', 'critical']
},
riskFactors: {
type: 'array',
description: 'Identified risk factors',
items: { type: 'string' }
},
mitigations: {
type: 'array',
description: 'Recommended risk mitigations',
items: { type: 'string' }
},
reviewRequired: {
type: 'boolean',
description: 'Whether human review is required'
},
questions: {
type: 'array',
description: 'Questions for requesting more information',
items: { type: 'string' }
}
},
required: ['decision', 'confidence', 'reasoning', 'riskLevel', 'reviewRequired']
}
};
// Create LLM request
const llmRequest = {
id: `delegation-decision-${request.requestId}`,
type: types_1.LLMRequestType.FUNCTION_CALL,
prompt,
agentDID: 'system-delegation-engine',
sessionId,
functions: [decisionFunction],
parameters: {
temperature: 0.3, // Lower temperature for consistent decisions
maxTokens: 1000
},
metadata: {
agentDID: 'system-delegation-engine',
sessionId,
requestId: `delegation-decision-${request.requestId}`,
timestamp: new Date(),
source: 'llm-delegation-engine',
priority: this.mapUrgencyToPriority(request.urgency),
delegationRequestId: request.requestId
}
};
// Route to LLM
const response = await this.messageRouter.routeMessage(llmRequest);
// Process response
const decision = await this.processDecisionResponse(response, request);
// Audit decision
if (this.config.auditAllDecisions) {
await this.auditDecision(request, decision, context);
}
// Emit decision event
this.emit('delegation_decision', {
request,
decision,
context
});
return decision;
}
catch (error) {
// Fallback to conservative decision
const fallbackDecision = {
requestId: request.requestId,
decision: 'deny',
confidence: 0,
reasoning: `Error during decision making: ${error.message}`,
warnings: ['Decision engine error', 'Defaulting to deny for security'],
riskAssessment: {
level: 'critical',
factors: ['Decision engine failure'],
mitigations: ['Manual review required']
},
decidedAt: new Date(),
reviewRequired: true
};
this.emit('delegation_error', {
request,
error,
fallbackDecision
});
return fallbackDecision;
}
}
/**
* Interpret policy using LLM
*/
async interpretPolicy(policyDocument, context, specificScenario) {
const sessionId = `policy-${Date.now()}`;
const prompt = this.buildPolicyInterpretationPrompt(policyDocument, context, specificScenario);
const interpretationFunction = {
name: 'interpret_policy',
description: 'Interpret organizational policy for delegation scenarios',
parameters: {
type: 'object',
properties: {
summary: {
type: 'string',
description: 'Brief summary of the policy'
},
applicableRules: {
type: 'array',
description: 'Rules that apply to the scenario',
items: {
type: 'object',
properties: {
rule: { type: 'string', description: 'Policy rule identifier' },
description: { type: 'string', description: 'Human readable rule description' },
impact: { type: 'string', description: 'Policy impact type', enum: ['allow', 'restrict', 'modify'] },
severity: { type: 'string', description: 'Severity level of policy violation', enum: ['info', 'warning', 'error'] }
}
}
},
requirements: {
type: 'array',
description: 'Requirements that must be met',
items: { type: 'string' }
},
restrictions: {
type: 'array',
description: 'Restrictions to be aware of',
items: { type: 'string' }
},
recommendations: {
type: 'array',
description: 'Best practice recommendations',
items: { type: 'string' }
},
exceptions: {
type: 'array',
description: 'Policy exceptions that may apply',
items: {
type: 'object',
properties: {
condition: { type: 'string', description: 'Condition that must be met' },
action: { type: 'string', description: 'Action to take when condition is met' },
justification: { type: 'string', description: 'Justification for the requirement' }
}
}
},
complianceLevel: {
type: 'number',
description: 'Overall compliance level (0-1)',
minimum: 0,
maximum: 1
}
},
required: ['summary', 'requirements', 'restrictions', 'complianceLevel']
}
};
const llmRequest = {
id: `policy-interpretation-${Date.now()}`,
type: types_1.LLMRequestType.FUNCTION_CALL,
prompt,
agentDID: 'system-policy-interpreter',
sessionId,
functions: [interpretationFunction],
parameters: {
temperature: 0.2,
maxTokens: 1500
},
metadata: {
agentDID: 'system-policy-interpreter',
sessionId,
requestId: `policy-interpretation-${Date.now()}`,
timestamp: new Date(),
source: 'llm-delegation-engine',
priority: types_1.RequestPriority.MEDIUM
}
};
const response = await this.messageRouter.routeMessage(llmRequest);
if (response.functionCall) {
const interpretation = response.functionCall.arguments;
interpretation.policyId = `policy-${Date.now()}`;
return interpretation;
}
throw new types_1.MCPError({
code: types_1.MCPErrorCode.FUNCTION_ERROR,
message: 'Failed to interpret policy',
timestamp: new Date(),
retryable: true
});
}
/**
* Generate scope recommendations
*/
async recommendScopes(requestedScopes, purpose, context, availableScopes) {
const sessionId = `scope-recommendation-${Date.now()}`;
const prompt = this.buildScopeRecommendationPrompt(requestedScopes, purpose, context, availableScopes);
const recommendationFunction = {
name: 'recommend_scopes',
description: 'Recommend optimal scopes for delegation',
parameters: {
type: 'object',
properties: {
recommendedScopes: {
type: 'array',
description: 'Recommended scopes based on principle of least privilege',
items: { type: 'string' }
},
reasoning: {
type: 'string',
description: 'Explanation for the recommendations'
},
alternatives: {
type: 'array',
description: 'Alternative scope configurations',
items: {
type: 'object',
properties: {
scopes: { type: 'array', description: 'Recommended scopes for delegation', items: { type: 'string' } },
rationale: { type: 'string', description: 'Reasoning behind the recommendation' },
tradeoffs: { type: 'array', description: 'Trade-offs to consider', items: { type: 'string' } }
}
}
},
minimumScopes: {
type: 'array',
description: 'Minimum scopes needed for the purpose',
items: { type: 'string' }
},
maximumScopes: {
type: 'array',
description: 'Maximum safe scopes for this delegation',
items: { type: 'string' }
},
riskLevel: {
type: 'string',
description: 'Risk level of recommended scopes',
enum: ['low', 'medium', 'high']
}
},
required: ['recommendedScopes', 'reasoning', 'minimumScopes', 'riskLevel']
}
};
const llmRequest = {
id: `scope-recommendation-${Date.now()}`,
type: types_1.LLMRequestType.FUNCTION_CALL,
prompt,
agentDID: 'system-scope-recommender',
sessionId,
functions: [recommendationFunction],
parameters: {
temperature: 0.4,
maxTokens: 800
},
metadata: {
agentDID: 'system-scope-recommender',
sessionId,
requestId: `scope-recommendation-${Date.now()}`,
timestamp: new Date(),
source: 'llm-delegation-engine',
priority: types_1.RequestPriority.MEDIUM
}
};
const response = await this.messageRouter.routeMessage(llmRequest);
if (response.functionCall) {
const recommendation = response.functionCall.arguments;
recommendation.requestedScopes = requestedScopes;
return recommendation;
}
// Fallback recommendation
return {
requestedScopes,
recommendedScopes: requestedScopes.slice(0, Math.ceil(requestedScopes.length / 2)),
reasoning: 'Conservative recommendation due to LLM processing error',
alternatives: [],
minimumScopes: requestedScopes.slice(0, 1),
maximumScopes: requestedScopes,
riskLevel: 'medium'
};
}
/**
* Process natural language delegation request
*/
async processNaturalLanguageRequest(naturalLanguageRequest, requestingAgentDID, context) {
const sessionId = `nl-request-${Date.now()}`;
const prompt = this.buildNaturalLanguagePrompt(naturalLanguageRequest, context);
const extractionFunction = {
name: 'extract_delegation_request',
description: 'Extract structured delegation request from natural language',
parameters: {
type: 'object',
properties: {
targetAgentDID: {
type: 'string',
description: 'Identified target agent DID or type'
},
requestedScopes: {
type: 'array',
description: 'Extracted scope requirements',
items: { type: 'string' }
},
purpose: {
type: 'string',
description: 'Clear purpose of the delegation'
},
urgency: {
type: 'string',
description: 'Urgency level inferred from request',
enum: ['low', 'medium', 'high', 'critical']
},
duration: {
type: 'number',
description: 'Requested duration in milliseconds (if specified)'
},
constraints: {
type: 'object',
description: 'Any constraints mentioned in the request'
},
clarificationNeeded: {
type: 'array',
description: 'Areas where clarification is needed',
items: { type: 'string' }
}
},
required: ['purpose', 'urgency']
}
};
const llmRequest = {
id: `nl-extraction-${Date.now()}`,
type: types_1.LLMRequestType.FUNCTION_CALL,
prompt,
agentDID: requestingAgentDID,
sessionId,
functions: [extractionFunction],
parameters: {
temperature: 0.3,
maxTokens: 600
},
metadata: {
agentDID: requestingAgentDID,
sessionId,
requestId: `nl-extraction-${Date.now()}`,
timestamp: new Date(),
source: 'llm-delegation-engine',
priority: types_1.RequestPriority.MEDIUM
}
};
const response = await this.messageRouter.routeMessage(llmRequest);
if (response.functionCall) {
const extracted = response.functionCall.arguments;
const delegationRequest = {
requestId: `req-${Date.now()}`,
parentAgentDID: requestingAgentDID,
targetAgentDID: extracted.targetAgentDID || 'auto-assign',
requestedScopes: extracted.requestedScopes || [],
purpose: extracted.purpose,
context: naturalLanguageRequest,
duration: extracted.duration,
constraints: extracted.constraints,
urgency: extracted.urgency,
requestedAt: new Date(),
metadata: {
naturalLanguageRequest,
clarificationNeeded: extracted.clarificationNeeded
}
};
return delegationRequest;
}
throw new types_1.MCPError({
code: types_1.MCPErrorCode.FUNCTION_ERROR,
message: 'Failed to extract delegation request from natural language',
timestamp: new Date(),
retryable: true
});
}
/**
* Build decision prompt
*/
buildDecisionPrompt(request, context) {
return `
As an AI security governance system, analyze the following delegation request and make a comprehensive decision.
DELEGATION REQUEST:
- Request ID: ${request.requestId}
- Parent Agent: ${request.parentAgentDID} (Trust Level: ${context.parentAgent.trustLevel})
- Target Agent: ${request.targetAgentDID || 'To be assigned'}
- Purpose: ${request.purpose}
- Requested Scopes: ${request.requestedScopes.join(', ')}
- Duration: ${request.duration ? `${request.duration}ms` : 'Not specified'}
- Urgency: ${request.urgency}
CONTEXT:
- System Security Level: ${context.securityLevel}
- Current Time: ${context.timeOfDay} (Working Hours: ${context.workingHours})
- System Load: CPU ${context.systemLoad.cpu}%, Memory ${context.systemLoad.memory}%, Active Agents: ${context.systemLoad.activeAgents}
- Parent Agent History: ${context.parentAgent.history.totalDelegations} total delegations, ${context.parentAgent.history.successfulDelegations} successful
- Current Delegations: ${context.currentDelegations.length} active
POLICIES TO CONSIDER:
- Maximum delegation depth: ${this.config.maxDelegationDepth}
- Minimum confidence threshold: ${this.config.minConfidenceThreshold}
- Organizational policies: ${context.organizationalPolicies.length} policies
- System policies: ${context.systemPolicies.length} policies
EVALUATION CRITERIA:
1. Security implications of the requested scopes
2. Trust level and history of requesting agent
3. Appropriateness of purpose for requested scopes
4. Current system state and load
5. Compliance with organizational policies
6. Risk mitigation strategies
Make a decision that balances security, functionality, and compliance. Consider the principle of least privilege and provide detailed reasoning for your decision.
`;
}
/**
* Build policy interpretation prompt
*/
buildPolicyInterpretationPrompt(policy, context, scenario) {
return `
Analyze the following organizational policy in the context of agent delegation:
POLICY DOCUMENT:
${JSON.stringify(policy, null, 2)}
CONTEXT:
- Security Level: ${context.securityLevel}
- Agent Type: ${context.parentAgent.type}
- Working Hours: ${context.workingHours}
- System Load: ${context.systemLoad.cpu}% CPU, ${context.systemLoad.memory}% Memory
${scenario ? `SPECIFIC SCENARIO:\n${scenario}` : ''}
Provide a comprehensive interpretation that focuses on:
1. How this policy applies to delegation scenarios
2. Specific rules that govern scope assignment
3. Requirements for different types of delegations
4. Restrictions and limitations
5. Exceptions and special circumstances
6. Compliance requirements
Be precise about which parts of the policy are mandatory vs. recommended.
`;
}
/**
* Build scope recommendation prompt
*/
buildScopeRecommendationPrompt(requestedScopes, purpose, context, availableScopes) {
return `
Recommend optimal scopes for the following delegation request:
PURPOSE: ${purpose}
REQUESTED SCOPES: ${requestedScopes.join(', ')}
AVAILABLE SCOPES: ${availableScopes.join(', ')}
CONTEXT:
- Parent Agent Trust Level: ${context.parentAgent.trustLevel}
- Security Level: ${context.securityLevel}
- Agent Type: ${context.parentAgent.type}
PRINCIPLES TO APPLY:
1. Principle of least privilege - grant minimum necessary access
2. Purpose limitation - scopes should align with stated purpose
3. Risk minimization - prefer lower-risk scope combinations
4. Functional adequacy - ensure delegated agent can accomplish the task
Analyze each requested scope and determine:
- Is it necessary for the stated purpose?
- What are the security implications?
- Are there safer alternatives?
- What is the minimum viable set of scopes?
Provide alternative configurations with different risk/functionality tradeoffs.
`;
}
/**
* Build natural language prompt
*/
buildNaturalLanguagePrompt(request, context) {
return `
Extract a structured delegation request from the following natural language request:
REQUEST: "${request}"
CONTEXT:
- Current time: ${context.timeOfDay}
- Working hours: ${context.workingHours}
- Available agent types: user, service, autonomous, assistant
- Common scopes: read, write, execute, admin, finance, hr, customer_service, data_analysis
Extract the following information:
1. What type of agent is being requested (or target agent if specified)
2. What permissions/scopes are needed
3. What is the purpose or goal
4. How urgent is this request
5. Any time constraints or duration
6. Any specific constraints or limitations mentioned
7. Any areas where clarification would be helpful
Be conservative in scope assignment and flag any ambiguous requests for clarification.
`;
}
/**
* Process decision response from LLM
*/
async processDecisionResponse(response, request) {
if (!response.functionCall) {
throw new types_1.MCPError({
code: types_1.MCPErrorCode.FUNCTION_ERROR,
message: 'No structured decision received from LLM',
timestamp: new Date(),
retryable: true
});
}
const args = response.functionCall.arguments;
// Validate decision confidence
if (args.confidence < this.config.minConfidenceThreshold && args.decision === 'approve') {
args.decision = 'request_more_info';
args.warnings = [...(args.warnings || []), 'Low confidence decision - requesting more information'];
}
// Apply human review requirement for high-risk decisions
if (this.config.requireHumanApproval || args.riskLevel === 'critical' || args.riskLevel === 'high') {
args.reviewRequired = true;
}
const decision = {
requestId: request.requestId,
decision: args.decision,
confidence: args.confidence,
reasoning: args.reasoning,
suggestedScopes: args.suggestedScopes,
suggestedConstraints: args.suggestedConstraints,
suggestedDuration: args.suggestedDuration,
warnings: args.warnings || [],
riskAssessment: {
level: args.riskLevel,
factors: args.riskFactors || [],
mitigations: args.mitigations || []
},
decidedAt: new Date(),
reviewRequired: args.reviewRequired,
additionalInfo: args.questions ? {
questions: args.questions,
expectedResponseTime: 3600000 // 1 hour
} : undefined
};
return decision;
}
/**
* Audit decision
*/
async auditDecision(request, decision, context) {
await this.auditLogger.logAuthorization(request.parentAgentDID, `delegation:${request.targetAgentDID}`, 'delegate', decision.decision === 'approve' || decision.decision === 'approve_with_modifications', decision.warnings);
this.emit('decision_audited', {
request,
decision,
context,
timestamp: new Date()
});
}
/**
* Map urgency to priority
*/
mapUrgencyToPriority(urgency) {
switch (urgency) {
case 'critical': return types_1.RequestPriority.CRITICAL;
case 'high': return types_1.RequestPriority.HIGH;
case 'medium': return types_1.RequestPriority.MEDIUM;
case 'low': return types_1.RequestPriority.LOW;
default: return types_1.RequestPriority.MEDIUM;
}
}
/**
* Initialize delegation-specific functions
*/
initializeDelegationFunctions() {
// Register delegation utility functions
this.functionRegistry.registerFunction({
name: 'assess_delegation_risk',
description: 'Assess risk level of a delegation request',
parameters: {
type: 'object',
properties: {
scopes: { type: 'array', description: 'Scopes to assess for risk', items: { type: 'string' } },
agentType: { type: 'string', description: 'Type of agent requesting delegation' },
purpose: { type: 'string', description: 'Purpose of the delegation request' }
},
required: ['scopes', 'agentType', 'purpose']
}
}, async (args) => {
// Risk assessment logic
const riskFactors = [];
let riskScore = 0;
// Check for high-risk scopes
const highRiskScopes = ['admin', 'delete', 'modify_permissions', 'system'];
const hasHighRiskScopes = args.scopes.some((scope) => highRiskScopes.some(risk => scope.toLowerCase().includes(risk)));
if (hasHighRiskScopes) {
riskScore += 0.4;
riskFactors.push('High-risk scopes detected');
}
// Check agent type risk
if (args.agentType === 'autonomous') {
riskScore += 0.3;
riskFactors.push('Autonomous agent type');
}
return {
riskScore,
riskLevel: riskScore > 0.7 ? 'high' : riskScore > 0.4 ? 'medium' : 'low',
riskFactors
};
});
}
/**
* Get delegation statistics
*/
getStatistics() {
// This would be tracked in a real implementation
return {
totalDecisions: 0,
approvalRate: 0,
averageConfidence: 0,
riskDistribution: {},
humanReviewRate: 0
};
}
/**
* Shutdown
*/
shutdown() {
this.functionRegistry.shutdown();
this.removeAllListeners();
}
}
exports.LLMDelegationEngine = LLMDelegationEngine;
exports.default = LLMDelegationEngine;
//# sourceMappingURL=llm-delegation-engine.js.map