export class VoiceMetrics { constructor() { this.startedAt = Date.now(); this.wakeAccepts = 0; this.wakeRejects = 0; this.feedbackDrops = 0; this.utterances = 0; this.replies = 0; this.synthesisCount = 0; this.synthesisMs = 0; this.audioMs = 0; } wakeAccepted() { this.wakeAccepts += 1; } wakeRejected() { this.wakeRejects += 1; } feedbackDrop() { this.feedbackDrops += 1; } utterance() { this.utterances += 1; } reply() { this.replies += 1; } synthesis(elapsedMs, audioMs) { this.synthesisCount += 1; this.synthesisMs += Math.max(0, Number(elapsedMs) || 0); this.audioMs += Math.max(0, Number(audioMs) || 0); } snapshot() { return { uptimeMs: Date.now() - this.startedAt, wakeAccepts: this.wakeAccepts, wakeRejects: this.wakeRejects, feedbackDrops: this.feedbackDrops, utterances: this.utterances, replies: this.replies, synthesisCount: this.synthesisCount, synthesisMs: this.synthesisMs, audioMs: this.audioMs, synthesisRealtimeFactor: this.audioMs > 0 ? this.synthesisMs / this.audioMs : null }; } }