From 2b7adeb22048328cb9cb4a91707bd3877791d97e Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 8 Dec 2025 23:17:11 +0100 Subject: [PATCH] VoiceWake: track listening state for PTT --- apps/macos/Sources/Clawdis/VoiceWakeRuntime.swift | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/macos/Sources/Clawdis/VoiceWakeRuntime.swift b/apps/macos/Sources/Clawdis/VoiceWakeRuntime.swift index 693147f48..f8ac48cdb 100644 --- a/apps/macos/Sources/Clawdis/VoiceWakeRuntime.swift +++ b/apps/macos/Sources/Clawdis/VoiceWakeRuntime.swift @@ -10,6 +10,8 @@ import AppKit actor VoiceWakeRuntime { static let shared = VoiceWakeRuntime() + enum ListeningState { case idle, voiceWake, pushToTalk } + private let logger = Logger(subsystem: "com.steipete.clawdis", category: "voicewake.runtime") private var recognizer: SFSpeechRecognizer? @@ -28,6 +30,7 @@ actor VoiceWakeRuntime { private var volatileTranscript: String = "" private var cooldownUntil: Date? private var currentConfig: RuntimeConfig? + private var listeningState: ListeningState = .idle // Tunables // Silence threshold once we've captured user speech (post-trigger). @@ -152,6 +155,7 @@ actor VoiceWakeRuntime { self.audioEngine.inputNode.removeTap(onBus: 0) self.audioEngine.stop() self.currentConfig = nil + self.listeningState = .idle self.logger.debug("voicewake runtime stopped") guard dismissOverlay else { return } @@ -224,6 +228,7 @@ actor VoiceWakeRuntime { } private func beginCapture(transcript: String, config: RuntimeConfig) async { + self.listeningState = .voiceWake self.isCapturing = true let trimmed = Self.trimmedAfterTrigger(transcript, triggers: config.triggers) self.capturedTranscript = trimmed @@ -360,7 +365,8 @@ actor VoiceWakeRuntime { } func pauseForPushToTalk() { - self.stop() + self.listeningState = .pushToTalk + self.stop(dismissOverlay: false) } private func updateHeardBeyondTrigger(withTrimmed trimmed: String) {