UNPKG

atp-sdk

Version:

Official TypeScript SDK for Agent Trust Protocol™ - Build secure, verifiable, and trustworthy applications with decentralized identity, verifiable credentials, payment protocols (AP2/ACP), and robust access control

187 lines 6.88 kB
/** * Enhanced Trust Scoring System for ATP™ SDK * * Provides multi-factor trust scoring based on: * - Interaction history and recency * - Credential verification status * - Behavioral patterns * - Time-weighted scoring */ /** * Trust level thresholds and their meanings */ export var TrustLevel; (function (TrustLevel) { TrustLevel["UNKNOWN"] = "UNKNOWN"; TrustLevel["BASIC"] = "BASIC"; TrustLevel["VERIFIED"] = "VERIFIED"; TrustLevel["TRUSTED"] = "TRUSTED"; TrustLevel["PRIVILEGED"] = "PRIVILEGED"; // 0.75-1.0 - High trust })(TrustLevel || (TrustLevel = {})); const DEFAULT_CONFIG = { interactionWeight: 0.25, recencyWeight: 0.25, credentialWeight: 0.30, successWeight: 0.20, recencyDecayPeriod: 30 * 24 * 60 * 60 * 1000, // 30 days minInteractionsForConfidence: 20 }; export class TrustScoring { constructor(config) { this.config = { ...DEFAULT_CONFIG, ...config }; } /** * Calculate a comprehensive trust score */ calculateTrustScore(interactions, verifiedCredentials = 0) { const now = new Date(); // Calculate individual factor scores const interactionScore = this.calculateInteractionScore(interactions.length); const recencyScore = this.calculateRecencyScore(interactions, now); const credentialScore = this.calculateCredentialScore(verifiedCredentials); const successScore = this.calculateSuccessScore(interactions); // Weighted combination const score = interactionScore * this.config.interactionWeight + recencyScore * this.config.recencyWeight + credentialScore * this.config.credentialWeight + successScore * this.config.successWeight; // Calculate confidence based on data availability const confidence = this.calculateConfidence(interactions.length, verifiedCredentials); // Determine trust level const level = this.scoreToLevel(score); // Calculate metadata const successfulInteractions = interactions.filter(i => i.success !== false).length; const lastInteraction = this.getLastInteraction(interactions); return { score: Math.round(score * 100) / 100, // Round to 2 decimal places level, factors: { interactionScore: Math.round(interactionScore * 100) / 100, recencyScore: Math.round(recencyScore * 100) / 100, credentialScore: Math.round(credentialScore * 100) / 100, successScore: Math.round(successScore * 100) / 100 }, confidence: Math.round(confidence * 100) / 100, metadata: { totalInteractions: interactions.length, successfulInteractions, lastInteractionAt: lastInteraction?.timestamp, credentialsVerified: verifiedCredentials, assessedAt: now.toISOString() } }; } /** * Calculate score based on number of interactions * Uses logarithmic scaling to handle large interaction counts */ calculateInteractionScore(count) { if (count === 0) return 0; if (count >= 100) return 1.0; // Logarithmic scaling: log(count+1) / log(101) for smooth curve return Math.min(1, Math.log(count + 1) / Math.log(101)); } /** * Calculate score based on recency of interactions * More recent interactions contribute more to the score */ calculateRecencyScore(interactions, now) { if (interactions.length === 0) return 0; const decayPeriod = this.config.recencyDecayPeriod; let totalWeight = 0; let recentWeight = 0; for (const interaction of interactions) { const age = now.getTime() - new Date(interaction.timestamp).getTime(); const weight = Math.max(0, 1 - age / decayPeriod); recentWeight += weight; totalWeight += 1; } if (totalWeight === 0) return 0; return recentWeight / totalWeight; } /** * Calculate score based on verified credentials */ calculateCredentialScore(verifiedCount) { if (verifiedCount === 0) return 0; if (verifiedCount >= 5) return 1.0; // Each credential adds 0.2 to the score up to 1.0 return Math.min(1, verifiedCount * 0.2); } /** * Calculate score based on success rate of interactions */ calculateSuccessScore(interactions) { if (interactions.length === 0) return 0.5; // Neutral if no data const explicitResults = interactions.filter(i => i.success !== undefined); if (explicitResults.length === 0) return 0.5; const successCount = explicitResults.filter(i => i.success === true).length; return successCount / explicitResults.length; } /** * Calculate confidence in the trust score */ calculateConfidence(interactionCount, credentialCount) { const interactionConfidence = Math.min(1, interactionCount / this.config.minInteractionsForConfidence); const credentialConfidence = Math.min(1, credentialCount * 0.25); // Weighted average of confidence factors return interactionConfidence * 0.7 + credentialConfidence * 0.3; } /** * Convert numerical score to trust level */ scoreToLevel(score) { if (score <= 0) return TrustLevel.UNKNOWN; if (score < 0.25) return TrustLevel.BASIC; if (score < 0.5) return TrustLevel.VERIFIED; if (score < 0.75) return TrustLevel.TRUSTED; return TrustLevel.PRIVILEGED; } /** * Get the most recent interaction */ getLastInteraction(interactions) { if (interactions.length === 0) return undefined; return interactions.reduce((latest, current) => { const latestTime = new Date(latest.timestamp).getTime(); const currentTime = new Date(current.timestamp).getTime(); return currentTime > latestTime ? current : latest; }); } /** * Get simple numeric score (for backward compatibility) */ static simpleScore(interactions) { const scorer = new TrustScoring(); return scorer.calculateTrustScore(interactions).score; } /** * Get trust level from simple interaction count (backward compatible) */ static levelFromCount(count) { if (count === 0) return 0; if (count < 5) return 0.25; if (count < 20) return 0.5; if (count < 50) return 0.75; return 1.0; } } export default TrustScoring; //# sourceMappingURL=trust.js.map