anon-identity
Version:
Decentralized identity framework with DIDs, Verifiable Credentials, and privacy-preserving selective disclosure
842 lines • 32.5 kB
JavaScript
"use strict";
/**
* Agent Matcher for MCP
*
* Embedding-based agent matching and capability discovery
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.AgentMatcher = void 0;
const events_1 = require("events");
const types_1 = require("../types");
/**
* Agent Matcher
*/
class AgentMatcher extends events_1.EventEmitter {
constructor(messageRouter, authManager, auditLogger, config = {
embeddingModel: 'text-embedding-ada-002',
similarityThreshold: 0.7,
maxResults: 10,
weightings: {
capabilityMatch: 0.3,
performance: 0.25,
availability: 0.15,
cost: 0.1,
trust: 0.1,
experience: 0.1
},
enableSemanticMatching: true,
enableLearning: true,
cacheEmbeddings: true
}) {
super();
this.messageRouter = messageRouter;
this.authManager = authManager;
this.auditLogger = auditLogger;
this.config = config;
this.agentProfiles = new Map();
this.taskEmbeddings = new Map();
this.agentEmbeddings = new Map();
this.matchHistory = [];
this.semanticCache = new Map();
this.loadAgentProfiles();
}
/**
* Register agent profile
*/
async registerAgent(profile) {
// Create temporary profile for embedding generation
const tempProfile = {
...profile,
embedding: [], // Will be replaced
lastUpdated: new Date()
};
// Generate embedding for agent capabilities
const embedding = await this.generateAgentEmbedding(tempProfile);
const fullProfile = {
...profile,
embedding,
lastUpdated: new Date()
};
this.agentProfiles.set(profile.agentDID, fullProfile);
this.agentEmbeddings.set(profile.agentDID, embedding);
await this.saveAgentProfiles();
this.emit('agent_registered', fullProfile);
}
/**
* Update agent profile
*/
async updateAgent(agentDID, updates) {
const existing = this.agentProfiles.get(agentDID);
if (!existing) {
throw new types_1.MCPError({
code: types_1.MCPErrorCode.INVALID_REQUEST,
message: `Agent profile not found: ${agentDID}`,
timestamp: new Date(),
retryable: false
});
}
const updated = { ...existing, ...updates, lastUpdated: new Date() };
// Regenerate embedding if capabilities changed
if (updates.capabilities || updates.expertise || updates.availableActions) {
updated.embedding = await this.generateAgentEmbedding(updated);
this.agentEmbeddings.set(agentDID, updated.embedding);
}
this.agentProfiles.set(agentDID, updated);
await this.saveAgentProfiles();
this.emit('agent_updated', updated);
}
/**
* Find matching agents for task
*/
async findMatches(task) {
// Generate task embedding
const taskEmbedding = await this.generateTaskEmbedding(task);
task.embedding = taskEmbedding;
this.taskEmbeddings.set(task.id, taskEmbedding);
// Get all available agents
const availableAgents = await this.getAvailableAgents(task);
if (availableAgents.length === 0) {
return [];
}
// Score and rank agents
const matches = [];
for (const agent of availableAgents) {
const match = await this.scoreAgentMatch(agent, task);
if (match.score >= this.config.similarityThreshold) {
matches.push(match);
}
}
// Sort by score (highest first)
matches.sort((a, b) => b.score - a.score);
// Apply learning adjustments if enabled
if (this.config.enableLearning) {
this.applyLearningAdjustments(matches, task);
}
// Return top results
const results = matches.slice(0, this.config.maxResults);
// Log matching request
await this.auditLogger.logRequest({
id: `matching-${task.id}`,
type: types_1.LLMRequestType.COMPLETION,
prompt: `Find agents for task: ${task.title}`,
agentDID: 'system-agent-matcher',
sessionId: `matching-${Date.now()}`,
metadata: {
agentDID: 'system-agent-matcher',
sessionId: `matching-${Date.now()}`,
requestId: `matching-${task.id}`,
timestamp: new Date(),
source: 'agent-matcher',
priority: types_1.RequestPriority.MEDIUM,
taskId: task.id
}
}, 'system-agent-matcher', `matching-${Date.now()}`);
this.emit('matches_found', { task, matches: results });
return results;
}
/**
* Find semantically similar agents
*/
async findSimilarAgents(agentDID, options = {}) {
const sourceAgent = this.agentProfiles.get(agentDID);
if (!sourceAgent || !sourceAgent.embedding) {
throw new types_1.MCPError({
code: types_1.MCPErrorCode.INVALID_REQUEST,
message: `Agent not found or missing embedding: ${agentDID}`,
timestamp: new Date(),
retryable: false
});
}
const similarities = [];
for (const [id, agent] of this.agentProfiles) {
if (id === agentDID)
continue; // Skip self
if (!agent.embedding)
continue;
const similarity = this.calculateCosineSimilarity(sourceAgent.embedding, agent.embedding);
if (similarity >= (options.minSimilarity || 0.5)) {
similarities.push({ agent, similarity });
}
}
// Sort by similarity
similarities.sort((a, b) => b.similarity - a.similarity);
// Return top results
return similarities.slice(0, options.maxResults || 10);
}
/**
* Recommend agents based on context
*/
async recommendAgents(context, options = {}) {
// Create synthetic task for recommendation
const syntheticTask = {
id: `recommendation-${Date.now()}`,
title: `${context.domain} task`,
description: `A ${context.complexity} ${context.domain} task`,
requiredCapabilities: [context.domain],
priority: context.urgency ? 'high' : 'medium',
constraints: {
maxCost: context.budget,
requiredCertifications: context.requiredCertifications
},
context: {
domain: context.domain,
urgency: context.urgency,
complexity: context.complexity,
estimatedDuration: this.estimateDurationByComplexity(context.complexity)
}
};
const matches = await this.findMatches(syntheticTask);
// Apply diversity if requested
if (options.diversityFactor && options.diversityFactor > 0) {
return this.diversifyResults(matches, options.diversityFactor);
}
return matches.slice(0, options.maxResults || 5);
}
/**
* Generate agent embedding
*/
async generateAgentEmbedding(agent) {
if (!this.config.enableSemanticMatching) {
return this.generateSimpleEmbedding(agent);
}
// Create text representation of agent capabilities
const agentText = [
agent.description,
...agent.capabilities,
...agent.expertise,
...agent.availableActions
].join(' ');
// Check cache first
const cacheKey = `agent:${this.hashString(agentText)}`;
if (this.config.cacheEmbeddings && this.semanticCache.has(cacheKey)) {
return this.semanticCache.get(cacheKey);
}
// Generate embedding using LLM
const embedding = await this.generateEmbedding(agentText);
// Cache result
if (this.config.cacheEmbeddings) {
this.semanticCache.set(cacheKey, embedding);
}
return embedding;
}
/**
* Generate task embedding
*/
async generateTaskEmbedding(task) {
if (!this.config.enableSemanticMatching) {
return this.generateSimpleTaskEmbedding(task);
}
// Create text representation of task requirements
const taskText = [
task.title,
task.description,
...task.requiredCapabilities,
...(task.preferredCapabilities || []),
task.context.domain,
task.context.complexity
].join(' ');
// Check cache first
const cacheKey = `task:${this.hashString(taskText)}`;
if (this.config.cacheEmbeddings && this.semanticCache.has(cacheKey)) {
return this.semanticCache.get(cacheKey);
}
// Generate embedding using LLM
const embedding = await this.generateEmbedding(taskText);
// Cache result
if (this.config.cacheEmbeddings) {
this.semanticCache.set(cacheKey, embedding);
}
return embedding;
}
/**
* Generate embedding using LLM
*/
async generateEmbedding(text) {
try {
const request = {
id: `embedding-${Date.now()}`,
type: types_1.LLMRequestType.EMBEDDING,
prompt: text,
agentDID: 'system-agent-matcher',
sessionId: `embedding-${Date.now()}`,
parameters: {
model: this.config.embeddingModel
},
metadata: {
agentDID: 'system-agent-matcher',
sessionId: `embedding-${Date.now()}`,
requestId: `embedding-${Date.now()}`,
timestamp: new Date(),
source: 'agent-matcher',
priority: types_1.RequestPriority.LOW
}
};
const response = await this.messageRouter.routeMessage(request);
if (response.embedding) {
return response.embedding;
}
throw new Error('No embedding returned from LLM');
}
catch (error) {
console.warn('Failed to generate semantic embedding, falling back to simple embedding:', error);
return this.generateSimpleEmbedding({ capabilities: [text] });
}
}
/**
* Generate simple embedding (fallback)
*/
generateSimpleEmbedding(agent) {
// Create a simple hash-based embedding
const features = [
...agent.capabilities,
...agent.expertise,
...agent.availableActions
];
const embedding = new Array(128).fill(0);
for (const feature of features) {
const hash = this.hashString(feature);
for (let i = 0; i < embedding.length; i++) {
embedding[i] += ((hash >> i) & 1) ? 1 : -1;
}
}
// Normalize
const magnitude = Math.sqrt(embedding.reduce((sum, val) => sum + val * val, 0));
return embedding.map(val => val / magnitude);
}
/**
* Generate simple task embedding
*/
generateSimpleTaskEmbedding(task) {
const features = [
...task.requiredCapabilities,
...(task.preferredCapabilities || []),
task.context.domain,
task.context.complexity
];
const embedding = new Array(128).fill(0);
for (const feature of features) {
const hash = this.hashString(feature);
for (let i = 0; i < embedding.length; i++) {
embedding[i] += ((hash >> i) & 1) ? 1 : -1;
}
}
// Normalize
const magnitude = Math.sqrt(embedding.reduce((sum, val) => sum + val * val, 0));
return embedding.map(val => val / magnitude);
}
/**
* Score agent match against task
*/
async scoreAgentMatch(agent, task) {
// Calculate base similarity using embeddings
let similarity = 0;
if (agent.embedding && task.embedding) {
similarity = this.calculateCosineSimilarity(agent.embedding, task.embedding);
}
// Calculate capability alignment
const capabilityAlignment = this.calculateCapabilityAlignment(agent, task);
// Calculate performance score
const performanceScore = this.calculatePerformanceScore(agent, task);
// Calculate availability score
const availabilityScore = this.calculateAvailabilityScore(agent, task);
// Calculate cost score
const costScore = this.calculateCostScore(agent, task);
// Calculate trust score
const trustScore = agent.trustLevel;
// Calculate experience score
const experienceScore = this.calculateExperienceScore(agent, task);
// Weighted total score
const score = similarity * this.config.weightings.capabilityMatch +
performanceScore * this.config.weightings.performance +
availabilityScore * this.config.weightings.availability +
costScore * this.config.weightings.cost +
trustScore * this.config.weightings.trust +
experienceScore * this.config.weightings.experience;
// Calculate confidence based on data quality
const confidence = this.calculateConfidence(agent, task, similarity);
// Generate reasoning
const reasoning = this.generateMatchReasoning(agent, task, score, capabilityAlignment, performanceScore);
// Risk assessment
const riskAssessment = this.assessRisk(agent, task);
// Estimated metrics
const estimatedMetrics = this.estimateTaskMetrics(agent, task);
return {
agent,
score: Math.min(1, Math.max(0, score)),
confidence,
reasoning,
capabilityAlignment,
riskAssessment,
estimatedMetrics
};
}
/**
* Calculate capability alignment
*/
calculateCapabilityAlignment(agent, task) {
const required = task.requiredCapabilities.map(capability => {
const match = agent.capabilities.some(ac => ac.toLowerCase().includes(capability.toLowerCase()) ||
capability.toLowerCase().includes(ac.toLowerCase()));
const strength = match ? this.calculateCapabilityStrength(agent, capability) : 0;
return { capability, match, strength };
});
const preferred = (task.preferredCapabilities || []).map(capability => {
const match = agent.capabilities.some(ac => ac.toLowerCase().includes(capability.toLowerCase()) ||
capability.toLowerCase().includes(ac.toLowerCase()));
const strength = match ? this.calculateCapabilityStrength(agent, capability) : 0;
return { capability, match, strength };
});
const additional = agent.capabilities
.filter(capability => !task.requiredCapabilities.some(rc => rc.toLowerCase().includes(capability.toLowerCase())) &&
!(task.preferredCapabilities || []).some(pc => pc.toLowerCase().includes(capability.toLowerCase())))
.map(capability => ({
capability,
strength: this.calculateCapabilityStrength(agent, capability)
}));
return { required, preferred, additional };
}
/**
* Calculate capability strength
*/
calculateCapabilityStrength(agent, capability) {
// Check if it's in expertise (higher weight)
if (agent.expertise.some(exp => exp.toLowerCase().includes(capability.toLowerCase()))) {
return 0.9;
}
// Check if it's in available actions
if (agent.availableActions.some(action => action.toLowerCase().includes(capability.toLowerCase()))) {
return 0.7;
}
// Check if it's in general capabilities
if (agent.capabilities.some(cap => cap.toLowerCase().includes(capability.toLowerCase()))) {
return 0.6;
}
return 0;
}
/**
* Calculate performance score
*/
calculatePerformanceScore(agent, task) {
const performance = agent.performance;
// Weighted performance score
const responseTimeScore = Math.max(0, 1 - (performance.averageResponseTime / 10000)); // Normalize to 10s max
const successScore = performance.successRate;
const reliabilityScore = performance.reliability;
const costScore = performance.costEfficiency;
return (responseTimeScore + successScore + reliabilityScore + costScore) / 4;
}
/**
* Calculate availability score
*/
calculateAvailabilityScore(agent, task) {
// Check working hours
if (agent.constraints.workingHours) {
const now = new Date();
const currentHour = now.getHours();
const startHour = parseInt(agent.constraints.workingHours.start.split(':')[0]);
const endHour = parseInt(agent.constraints.workingHours.end.split(':')[0]);
if (currentHour < startHour || currentHour > endHour) {
return 0.3; // Reduced availability outside working hours
}
}
// Check concurrent task capacity
// This would need to be tracked externally
const estimatedUtilization = 0.5; // Mock value
return Math.max(0, 1 - estimatedUtilization);
}
/**
* Calculate cost score
*/
calculateCostScore(agent, task) {
const estimatedCost = this.estimateTaskCost(agent, task);
const maxCost = task.constraints.maxCost || 100;
return Math.max(0, 1 - (estimatedCost / maxCost));
}
/**
* Calculate experience score
*/
calculateExperienceScore(agent, task) {
// This would be based on historical performance in similar tasks
// For now, use expertise alignment
const domainExpertise = agent.expertise.some(exp => exp.toLowerCase().includes(task.context.domain.toLowerCase()));
const complexityMatch = this.getComplexityScore(agent, task.context.complexity);
return domainExpertise ? 0.8 + complexityMatch * 0.2 : complexityMatch;
}
/**
* Get complexity score
*/
getComplexityScore(agent, complexity) {
// This would ideally be based on historical data
const complexityScores = {
simple: 0.9,
moderate: 0.7,
complex: 0.5,
expert: agent.expertise.length > 3 ? 0.8 : 0.3
};
return complexityScores[complexity] || 0.5;
}
/**
* Calculate confidence
*/
calculateConfidence(agent, task, similarity) {
// Base confidence on data quality and match strength
let confidence = 0.5;
// Boost confidence for strong similarity
if (similarity > 0.8)
confidence += 0.3;
else if (similarity > 0.6)
confidence += 0.2;
else if (similarity > 0.4)
confidence += 0.1;
// Boost confidence for complete agent profile
if (agent.performance.averageResponseTime > 0)
confidence += 0.1;
if (agent.trustLevel > 0.8)
confidence += 0.1;
if (agent.expertise.length > 0)
confidence += 0.1;
return Math.min(1, confidence);
}
/**
* Generate match reasoning
*/
generateMatchReasoning(agent, task, score, capabilityAlignment, performanceScore) {
const reasons = [];
const requiredMatches = capabilityAlignment.required.filter(r => r.match).length;
const requiredTotal = capabilityAlignment.required.length;
reasons.push(`Matches ${requiredMatches}/${requiredTotal} required capabilities`);
if (performanceScore > 0.8) {
reasons.push('Excellent performance history');
}
else if (performanceScore > 0.6) {
reasons.push('Good performance history');
}
if (agent.trustLevel > 0.8) {
reasons.push('High trust level');
}
const preferredMatches = capabilityAlignment.preferred.filter(p => p.match).length;
if (preferredMatches > 0) {
reasons.push(`Matches ${preferredMatches} preferred capabilities`);
}
return `Score: ${(score * 100).toFixed(1)}%. ${reasons.join(', ')}.`;
}
/**
* Assess risk
*/
assessRisk(agent, task) {
const factors = [];
const mitigations = [];
// Trust level risk
if (agent.trustLevel < 0.5) {
factors.push('Low trust level');
mitigations.push('Require additional oversight');
}
// Performance risk
if (agent.performance.successRate < 0.8) {
factors.push('Below average success rate');
mitigations.push('Monitor progress closely');
}
// Capability mismatch risk
const requiredMatches = task.requiredCapabilities.filter(req => agent.capabilities.some(cap => cap.toLowerCase().includes(req.toLowerCase()))).length;
if (requiredMatches < task.requiredCapabilities.length) {
factors.push('Missing some required capabilities');
mitigations.push('Provide additional training or support');
}
// Data classification risk
if (task.constraints.dataClassification === 'restricted' && agent.trustLevel < 0.9) {
factors.push('Restricted data access with moderate trust');
mitigations.push('Enhanced security monitoring');
}
const level = factors.length === 0 ? 'low' :
factors.length <= 2 ? 'medium' : 'high';
return { level, factors, mitigations };
}
/**
* Estimate task metrics
*/
estimateTaskMetrics(agent, task) {
const cost = this.estimateTaskCost(agent, task);
const duration = this.estimateTaskDuration(agent, task);
const successProbability = Math.min(1, agent.performance.successRate +
(agent.trustLevel - 0.5) * 0.2); // Adjust based on trust
return { cost, duration, successProbability };
}
/**
* Estimate task cost
*/
estimateTaskCost(agent, task) {
// Base cost calculation (simplified)
const complexityMultiplier = {
simple: 1,
moderate: 2,
complex: 4,
expert: 8
};
const baseCost = 10; // Base cost units
const complexity = complexityMultiplier[task.context.complexity] || 1;
const efficiency = agent.performance.costEfficiency || 0.5;
return baseCost * complexity / efficiency;
}
/**
* Estimate task duration
*/
estimateTaskDuration(agent, task) {
const baseTime = this.estimateDurationByComplexity(task.context.complexity);
const efficiency = agent.performance.averageResponseTime / 1000; // Convert to seconds
return Math.max(300, baseTime * (1 + efficiency / 10)); // Minimum 5 minutes
}
/**
* Estimate duration by complexity
*/
estimateDurationByComplexity(complexity) {
const durations = {
simple: 1800, // 30 minutes
moderate: 3600, // 1 hour
complex: 7200, // 2 hours
expert: 14400 // 4 hours
};
return durations[complexity] || 3600;
}
/**
* Get available agents
*/
async getAvailableAgents(task) {
const available = [];
for (const [, agent] of this.agentProfiles) {
// Check trust level requirement
if (task.constraints.minTrustLevel && agent.trustLevel < task.constraints.minTrustLevel) {
continue;
}
// Check data restrictions
if (this.hasDataRestrictions(agent, task)) {
continue;
}
// Check certifications
if (task.constraints.requiredCertifications) {
// This would check against agent certifications
// For now, assume all agents are certified
}
available.push(agent);
}
return available;
}
/**
* Check data restrictions
*/
hasDataRestrictions(agent, task) {
if (!task.constraints.dataClassification)
return false;
const restrictionLevel = {
public: 0,
internal: 1,
confidential: 2,
restricted: 3
};
const taskLevel = restrictionLevel[task.constraints.dataClassification] || 0;
// Check if agent has sufficient clearance (simplified)
const agentClearance = agent.trustLevel >= 0.9 ? 3 :
agent.trustLevel >= 0.7 ? 2 :
agent.trustLevel >= 0.5 ? 1 : 0;
return agentClearance < taskLevel;
}
/**
* Apply learning adjustments
*/
applyLearningAdjustments(matches, task) {
if (!this.config.enableLearning)
return;
// Adjust scores based on historical performance
for (const match of matches) {
const history = this.matchHistory.filter(h => h.selectedAgent === match.agent.agentDID &&
h.outcome === 'success');
if (history.length > 0) {
const successRate = history.length /
this.matchHistory.filter(h => h.selectedAgent === match.agent.agentDID).length;
// Boost score for agents with good track record
match.score *= (0.8 + successRate * 0.2);
match.score = Math.min(1, match.score);
}
}
// Re-sort after adjustments
matches.sort((a, b) => b.score - a.score);
}
/**
* Diversify results
*/
diversifyResults(matches, diversityFactor) {
if (matches.length <= 1)
return matches;
const diversified = [matches[0]]; // Always include top match
const remaining = matches.slice(1);
while (diversified.length < matches.length && remaining.length > 0) {
let maxDiversity = -1;
let bestIndex = 0;
for (let i = 0; i < remaining.length; i++) {
const candidate = remaining[i];
let minSimilarity = 1;
// Find minimum similarity to already selected agents
for (const selected of diversified) {
if (candidate.agent.embedding && selected.agent.embedding) {
const similarity = this.calculateCosineSimilarity(candidate.agent.embedding, selected.agent.embedding);
minSimilarity = Math.min(minSimilarity, similarity);
}
}
const diversity = 1 - minSimilarity;
const combinedScore = candidate.score * (1 - diversityFactor) + diversity * diversityFactor;
if (combinedScore > maxDiversity) {
maxDiversity = combinedScore;
bestIndex = i;
}
}
diversified.push(remaining[bestIndex]);
remaining.splice(bestIndex, 1);
}
return diversified;
}
/**
* Calculate cosine similarity
*/
calculateCosineSimilarity(a, b) {
if (a.length !== b.length)
return 0;
let dotProduct = 0;
let normA = 0;
let normB = 0;
for (let i = 0; i < a.length; i++) {
dotProduct += a[i] * b[i];
normA += a[i] * a[i];
normB += b[i] * b[i];
}
const magnitude = Math.sqrt(normA) * Math.sqrt(normB);
return magnitude === 0 ? 0 : dotProduct / magnitude;
}
/**
* Hash string to number
*/
hashString(str) {
let hash = 0;
for (let i = 0; i < str.length; i++) {
const char = str.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash; // Convert to 32-bit integer
}
return Math.abs(hash);
}
/**
* Record match outcome for learning
*/
async recordMatchOutcome(taskId, selectedAgentDID, outcome, actualMetrics) {
const matchRecord = this.matchHistory.find(h => h.taskId === taskId);
if (matchRecord) {
matchRecord.selectedAgent = selectedAgentDID;
matchRecord.outcome = outcome;
matchRecord.actualMetrics = actualMetrics;
}
else {
this.matchHistory.push({
taskId,
matches: [], // Would be populated from original match
selectedAgent: selectedAgentDID,
outcome,
actualMetrics,
timestamp: new Date()
});
}
// Update agent performance based on outcome
const agent = this.agentProfiles.get(selectedAgentDID);
if (agent) {
this.updateAgentPerformance(agent, outcome, actualMetrics);
}
this.emit('match_outcome_recorded', {
taskId,
selectedAgentDID,
outcome,
actualMetrics
});
}
/**
* Update agent performance
*/
updateAgentPerformance(agent, outcome, actualMetrics) {
// Simple running average update
const alpha = 0.1; // Learning rate
if (outcome === 'success') {
agent.performance.successRate = agent.performance.successRate * (1 - alpha) + alpha;
}
else {
agent.performance.successRate = agent.performance.successRate * (1 - alpha);
}
// Update other metrics (simplified)
agent.performance.averageResponseTime =
agent.performance.averageResponseTime * (1 - alpha) + actualMetrics.duration * alpha;
agent.lastUpdated = new Date();
}
/**
* Load agent profiles
*/
async loadAgentProfiles() {
// This would load from persistent storage
// For now, create some mock profiles
const mockProfiles = [
{
agentDID: 'did:key:customer-service-bot',
name: 'Customer Service Assistant',
description: 'Specialized in customer support and service inquiries',
capabilities: ['customer_service', 'chat_support', 'ticket_management'],
expertise: ['customer_relations', 'problem_solving'],
availableActions: ['answer_questions', 'create_tickets', 'escalate_issues'],
performance: {
averageResponseTime: 2000,
successRate: 0.92,
reliability: 0.95,
costEfficiency: 0.8
},
constraints: {
maxConcurrentTasks: 10,
dataRestrictions: [],
geographicLimitations: []
},
lastUpdated: new Date(),
trustLevel: 0.85
}
];
for (const profile of mockProfiles) {
await this.registerAgent(profile);
}
}
/**
* Save agent profiles
*/
async saveAgentProfiles() {
// This would save to persistent storage
// For now, just emit event
this.emit('profiles_saved', Array.from(this.agentProfiles.values()));
}
/**
* Get matching statistics
*/
getStatistics() {
const totalMatches = this.matchHistory.length;
const successfulMatches = this.matchHistory.filter(h => h.outcome === 'success').length;
return {
totalProfiles: this.agentProfiles.size,
totalMatches,
averageMatchScore: 0.75, // Would calculate from history
successRate: totalMatches > 0 ? successfulMatches / totalMatches : 0,
embeddingCacheSize: this.semanticCache.size
};
}
/**
* Shutdown
*/
shutdown() {
this.agentProfiles.clear();
this.taskEmbeddings.clear();
this.agentEmbeddings.clear();
this.semanticCache.clear();
this.removeAllListeners();
}
}
exports.AgentMatcher = AgentMatcher;
exports.default = AgentMatcher;
//# sourceMappingURL=agent-matcher.js.map