Files
openclaw/apps/macos/Sources/OpenClaw/VoiceWakeRecognitionDebugSupport.swift
2026-03-02 11:32:20 +00:00

63 lines
1.9 KiB
Swift

import Foundation
import SwabbleKit
enum VoiceWakeRecognitionDebugSupport {
struct TranscriptSummary {
let textOnly: Bool
let timingCount: Int
}
static func shouldLogTranscript(
transcript: String,
isFinal: Bool,
loggerLevel: Logger.Level,
lastLoggedText: inout String?,
lastLoggedAt: inout Date?,
minRepeatInterval: TimeInterval = 0.25) -> Bool
{
guard !transcript.isEmpty else { return false }
guard loggerLevel == .debug || loggerLevel == .trace else { return false }
if transcript == lastLoggedText,
!isFinal,
let last = lastLoggedAt,
Date().timeIntervalSince(last) < minRepeatInterval
{
return false
}
lastLoggedText = transcript
lastLoggedAt = Date()
return true
}
static func textOnlyFallbackMatch(
transcript: String,
triggers: [String],
config: WakeWordGateConfig,
trimWake: (String, [String]) -> String) -> WakeWordGateMatch?
{
guard let command = VoiceWakeTextUtils.textOnlyCommand(
transcript: transcript,
triggers: triggers,
minCommandLength: config.minCommandLength,
trimWake: trimWake)
else { return nil }
return WakeWordGateMatch(triggerEndTime: 0, postGap: 0, command: command)
}
static func transcriptSummary(
transcript: String,
triggers: [String],
segments: [WakeWordSegment]) -> TranscriptSummary
{
TranscriptSummary(
textOnly: WakeWordGate.matchesTextOnly(text: transcript, triggers: triggers),
timingCount: segments.count(where: { $0.start > 0 || $0.duration > 0 }))
}
static func matchSummary(_ match: WakeWordGateMatch?) -> String {
match.map {
"match=true gap=\(String(format: "%.2f", $0.postGap))s cmdLen=\($0.command.count)"
} ?? "match=false"
}
}