UNPKG

@juspay/neurolink

Version:

Universal AI Development Platform with working MCP integration, multi-provider support, voice (TTS/STT/realtime), and professional CLI. 58+ external MCP servers discoverable, multimodal file processing, RAG pipelines. Build, test, and deploy AI applicatio

247 lines (246 loc) 8.07 kB
/** * @file Sampling Strategy * Configurable sampling for cost-efficient evaluation */ /** * Default sampling configuration */ export const DEFAULT_SAMPLING_CONFIG = { rate: 1.0, // 100% sampling by default alwaysEvaluate: { errors: true, }, adaptive: { enabled: false, qualityThreshold: 0.7, minRate: 0.1, maxRate: 1.0, }, }; const DEFAULT_ADAPTIVE_CONFIG = { enabled: false, qualityThreshold: 0.7, minRate: 0.1, maxRate: 1.0, }; /** * Sampling strategy for evaluation */ export class SamplingStrategy { _config; _recentScores = []; _currentRate; _maxRecentScores = 100; constructor(config = {}) { const clamp01 = (v) => Math.max(0, Math.min(1, v)); const defaultAdaptive = DEFAULT_SAMPLING_CONFIG.adaptive ?? DEFAULT_ADAPTIVE_CONFIG; const rawRate = config.rate ?? DEFAULT_SAMPLING_CONFIG.rate; const rawMinRate = config.adaptive?.minRate ?? defaultAdaptive.minRate; const rawMaxRate = config.adaptive?.maxRate ?? defaultAdaptive.maxRate; const minRate = clamp01(Math.min(rawMinRate, rawMaxRate)); const maxRate = clamp01(Math.max(rawMinRate, rawMaxRate)); this._config = { ...DEFAULT_SAMPLING_CONFIG, ...config, rate: clamp01(rawRate), alwaysEvaluate: { ...DEFAULT_SAMPLING_CONFIG.alwaysEvaluate, ...(config.alwaysEvaluate ?? {}), }, adaptive: { enabled: config.adaptive?.enabled ?? defaultAdaptive.enabled, qualityThreshold: clamp01(config.adaptive?.qualityThreshold ?? defaultAdaptive.qualityThreshold), minRate, maxRate, }, }; this._currentRate = this._config.rate; } /** * Get current sampling configuration */ get config() { return this._config; } /** * Get current sampling rate */ get currentRate() { return this._currentRate; } /** * Decide whether to sample a request */ shouldSample(context) { // Always evaluate errors if (context?.hasError && this._config.alwaysEvaluate?.errors) { return { shouldSample: true, reason: "Always evaluate errors", currentRate: this._currentRate, }; } // Always evaluate specific users if (context?.userId && this._config.alwaysEvaluate?.users?.includes(context.userId)) { return { shouldSample: true, reason: `Always evaluate user: ${context.userId}`, currentRate: this._currentRate, }; } // Always evaluate specific tags if (context?.tags && this._config.alwaysEvaluate?.tags) { const matchingTags = context.tags.filter((tag) => this._config.alwaysEvaluate?.tags?.includes(tag)); if (matchingTags.length > 0) { return { shouldSample: true, reason: `Always evaluate tags: ${matchingTags.join(", ")}`, currentRate: this._currentRate, }; } } // Random sampling based on current rate const random = Math.random(); const shouldSample = random < this._currentRate; return { shouldSample, reason: shouldSample ? `Sampled at ${(this._currentRate * 100).toFixed(1)}% rate` : `Not sampled (rate: ${(this._currentRate * 100).toFixed(1)}%)`, currentRate: this._currentRate, }; } /** * Record a score for adaptive sampling */ recordScore(score) { if (!Number.isFinite(score)) { return; } const boundedScore = Math.max(0, Math.min(10, score)); this._recentScores.push(boundedScore); // Keep only recent scores if (this._recentScores.length > this._maxRecentScores) { this._recentScores.shift(); } // Update adaptive rate if enabled if (this._config.adaptive?.enabled) { this._updateAdaptiveRate(); } } /** * Update sampling rate based on recent quality */ _updateAdaptiveRate() { if (!this._config.adaptive?.enabled || this._recentScores.length < 10) { return; } const adaptive = this._config.adaptive; const avgScore = this._recentScores.reduce((sum, s) => sum + s, 0) / this._recentScores.length; // Normalize to 0-1 scale (assuming 0-10 scores) const normalizedAvg = avgScore / 10; if (normalizedAvg < adaptive.qualityThreshold) { // Low quality - increase sampling rate this._currentRate = Math.min(adaptive.maxRate, this._currentRate * 1.2); } else { // High quality - can decrease sampling rate this._currentRate = Math.max(adaptive.minRate, this._currentRate * 0.9); } } /** * Reset sampling state */ reset() { this._recentScores = []; this._currentRate = this._config.rate; } /** * Update sampling configuration */ configure(config) { const clamp01 = (v) => Math.max(0, Math.min(1, v)); const currentAdaptive = this._config.adaptive ?? DEFAULT_SAMPLING_CONFIG.adaptive ?? DEFAULT_ADAPTIVE_CONFIG; const rawRate = config.rate ?? this._config.rate; const rawMinRate = config.adaptive?.minRate ?? currentAdaptive.minRate; const rawMaxRate = config.adaptive?.maxRate ?? currentAdaptive.maxRate; const minRate = clamp01(Math.min(rawMinRate, rawMaxRate)); const maxRate = clamp01(Math.max(rawMinRate, rawMaxRate)); this._config = { ...this._config, ...config, rate: clamp01(rawRate), alwaysEvaluate: { ...this._config.alwaysEvaluate, ...(config.alwaysEvaluate ?? {}), }, adaptive: { enabled: config.adaptive?.enabled ?? currentAdaptive.enabled, qualityThreshold: clamp01(config.adaptive?.qualityThreshold ?? currentAdaptive.qualityThreshold), minRate, maxRate, }, }; this._currentRate = this._config.rate; } /** * Get sampling statistics */ getStats() { const avgScore = this._recentScores.length > 0 ? this._recentScores.reduce((sum, s) => sum + s, 0) / this._recentScores.length : null; return { currentRate: this._currentRate, recentScoresCount: this._recentScores.length, averageScore: avgScore, }; } } /** * Create a sampling strategy */ export function createSamplingStrategy(config) { return new SamplingStrategy(config); } /** * Pre-configured sampling strategies */ export const SamplingStrategies = { /** Evaluate everything (default) */ all: () => new SamplingStrategy({ rate: 1.0 }), /** Evaluate 50% of requests */ half: () => new SamplingStrategy({ rate: 0.5 }), /** Evaluate 10% of requests */ light: () => new SamplingStrategy({ rate: 0.1 }), /** Adaptive sampling based on quality */ adaptive: () => new SamplingStrategy({ rate: 0.5, adaptive: { enabled: true, qualityThreshold: 0.7, minRate: 0.1, maxRate: 1.0, }, }), /** Only evaluate errors and specific conditions */ errorsOnly: () => new SamplingStrategy({ rate: 0.0, alwaysEvaluate: { errors: true, }, }), /** VIP users always evaluated */ vipUsers: (users) => new SamplingStrategy({ rate: 0.1, alwaysEvaluate: { errors: true, users, }, }), };