refactor: centralize talk silence timeout defaults
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
package ai.openclaw.app.voice
|
||||
|
||||
internal object TalkDefaults {
|
||||
const val defaultSilenceTimeoutMs = 700L
|
||||
}
|
||||
@@ -60,7 +60,6 @@ class TalkModeManager(
|
||||
private const val defaultModelIdFallback = "eleven_v3"
|
||||
private const val defaultOutputFormatFallback = "pcm_24000"
|
||||
private const val defaultTalkProvider = "elevenlabs"
|
||||
private const val defaultSilenceTimeoutMs = 700L
|
||||
private const val listenWatchdogMs = 12_000L
|
||||
private const val chatFinalWaitWithSubscribeMs = 45_000L
|
||||
private const val chatFinalWaitWithoutSubscribeMs = 6_000L
|
||||
@@ -118,11 +117,12 @@ class TalkModeManager(
|
||||
}
|
||||
|
||||
internal fun resolvedSilenceTimeoutMs(talk: JsonObject?): Long {
|
||||
val primitive = talk?.get("silenceTimeoutMs") as? JsonPrimitive ?: return defaultSilenceTimeoutMs
|
||||
if (primitive.isString) return defaultSilenceTimeoutMs
|
||||
val timeout = primitive.content.toDoubleOrNull() ?: return defaultSilenceTimeoutMs
|
||||
val fallback = TalkDefaults.defaultSilenceTimeoutMs
|
||||
val primitive = talk?.get("silenceTimeoutMs") as? JsonPrimitive ?: return fallback
|
||||
if (primitive.isString) return fallback
|
||||
val timeout = primitive.content.toDoubleOrNull() ?: return fallback
|
||||
if (timeout <= 0 || timeout % 1.0 != 0.0 || timeout > Long.MAX_VALUE.toDouble()) {
|
||||
return defaultSilenceTimeoutMs
|
||||
return fallback
|
||||
}
|
||||
return timeout.toLong()
|
||||
}
|
||||
@@ -155,7 +155,7 @@ class TalkModeManager(
|
||||
private var listeningMode = false
|
||||
|
||||
private var silenceJob: Job? = null
|
||||
private var silenceWindowMs = defaultSilenceTimeoutMs
|
||||
private var silenceWindowMs = TalkDefaults.defaultSilenceTimeoutMs
|
||||
private var lastTranscript: String = ""
|
||||
private var lastHeardAtMs: Long? = null
|
||||
private var lastSpokenText: String? = null
|
||||
@@ -1467,7 +1467,7 @@ class TalkModeManager(
|
||||
}
|
||||
configLoaded = true
|
||||
} catch (_: Throwable) {
|
||||
silenceWindowMs = defaultSilenceTimeoutMs
|
||||
silenceWindowMs = TalkDefaults.defaultSilenceTimeoutMs
|
||||
defaultVoiceId = envVoice?.takeIf { it.isNotEmpty() } ?: sagVoice?.takeIf { it.isNotEmpty() }
|
||||
defaultModelId = defaultModelIdFallback
|
||||
if (!modelOverrideActive) currentModelId = defaultModelId
|
||||
|
||||
@@ -94,20 +94,20 @@ class TalkModeConfigParsingTest {
|
||||
|
||||
@Test
|
||||
fun defaultsSilenceTimeoutMsWhenMissing() {
|
||||
assertEquals(700L, TalkModeManager.resolvedSilenceTimeoutMs(null))
|
||||
assertEquals(TalkDefaults.defaultSilenceTimeoutMs, TalkModeManager.resolvedSilenceTimeoutMs(null))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun defaultsSilenceTimeoutMsWhenInvalid() {
|
||||
val talk = buildJsonObject { put("silenceTimeoutMs", 0) }
|
||||
|
||||
assertEquals(700L, TalkModeManager.resolvedSilenceTimeoutMs(talk))
|
||||
assertEquals(TalkDefaults.defaultSilenceTimeoutMs, TalkModeManager.resolvedSilenceTimeoutMs(talk))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun defaultsSilenceTimeoutMsWhenString() {
|
||||
val talk = buildJsonObject { put("silenceTimeoutMs", "1500") }
|
||||
|
||||
assertEquals(700L, TalkModeManager.resolvedSilenceTimeoutMs(talk))
|
||||
assertEquals(TalkDefaults.defaultSilenceTimeoutMs, TalkModeManager.resolvedSilenceTimeoutMs(talk))
|
||||
}
|
||||
}
|
||||
|
||||
3
apps/ios/Sources/Voice/TalkDefaults.swift
Normal file
3
apps/ios/Sources/Voice/TalkDefaults.swift
Normal file
@@ -0,0 +1,3 @@
|
||||
enum TalkDefaults {
|
||||
static let silenceTimeoutMs = 900
|
||||
}
|
||||
@@ -34,7 +34,7 @@ final class TalkModeManager: NSObject {
|
||||
private typealias SpeechRequest = SFSpeechAudioBufferRecognitionRequest
|
||||
private static let defaultModelIdFallback = "eleven_v3"
|
||||
private static let defaultTalkProvider = "elevenlabs"
|
||||
private static let defaultSilenceTimeoutMs = 900
|
||||
private static let defaultSilenceTimeoutMs = TalkDefaults.silenceTimeoutMs
|
||||
private static let redactedConfigSentinel = "__OPENCLAW_REDACTED__"
|
||||
var isEnabled: Bool = false
|
||||
var isListening: Bool = false
|
||||
|
||||
@@ -60,7 +60,7 @@ import Testing
|
||||
}
|
||||
|
||||
@Test func defaultsSilenceTimeoutMsWhenMissing() {
|
||||
#expect(TalkModeManager.resolvedSilenceTimeoutMs(nil) == 900)
|
||||
#expect(TalkModeManager.resolvedSilenceTimeoutMs(nil) == TalkDefaults.silenceTimeoutMs)
|
||||
}
|
||||
|
||||
@Test func defaultsSilenceTimeoutMsWhenInvalid() {
|
||||
@@ -68,7 +68,7 @@ import Testing
|
||||
"silenceTimeoutMs": 0,
|
||||
]
|
||||
|
||||
#expect(TalkModeManager.resolvedSilenceTimeoutMs(TalkConfigParsing.bridgeFoundationDictionary(talk)) == 900)
|
||||
#expect(TalkModeManager.resolvedSilenceTimeoutMs(TalkConfigParsing.bridgeFoundationDictionary(talk)) == TalkDefaults.silenceTimeoutMs)
|
||||
}
|
||||
|
||||
@Test func defaultsSilenceTimeoutMsWhenBool() {
|
||||
@@ -76,6 +76,6 @@ import Testing
|
||||
"silenceTimeoutMs": true,
|
||||
]
|
||||
|
||||
#expect(TalkModeManager.resolvedSilenceTimeoutMs(TalkConfigParsing.bridgeFoundationDictionary(talk)) == 900)
|
||||
#expect(TalkModeManager.resolvedSilenceTimeoutMs(TalkConfigParsing.bridgeFoundationDictionary(talk)) == TalkDefaults.silenceTimeoutMs)
|
||||
}
|
||||
}
|
||||
|
||||
3
apps/macos/Sources/OpenClaw/TalkDefaults.swift
Normal file
3
apps/macos/Sources/OpenClaw/TalkDefaults.swift
Normal file
@@ -0,0 +1,3 @@
|
||||
enum TalkDefaults {
|
||||
static let silenceTimeoutMs = 700
|
||||
}
|
||||
@@ -12,7 +12,7 @@ actor TalkModeRuntime {
|
||||
private let ttsLogger = Logger(subsystem: "ai.openclaw", category: "talk.tts")
|
||||
private static let defaultModelIdFallback = "eleven_v3"
|
||||
private static let defaultTalkProvider = "elevenlabs"
|
||||
private static let defaultSilenceTimeoutMs = 700
|
||||
private static let defaultSilenceTimeoutMs = TalkDefaults.silenceTimeoutMs
|
||||
|
||||
private final class RMSMeter: @unchecked Sendable {
|
||||
private let lock = NSLock()
|
||||
|
||||
@@ -33,7 +33,7 @@ struct TalkModeConfigParsingTests {
|
||||
#expect(selection?.config["apiKey"]?.stringValue == "legacy-key")
|
||||
}
|
||||
|
||||
@Test func readsConfiguredSilenceTimeoutMs() {
|
||||
@Test func `reads configured silence timeout ms`() {
|
||||
let talk: [String: AnyCodable] = [
|
||||
"silenceTimeoutMs": AnyCodable(1500),
|
||||
]
|
||||
@@ -41,15 +41,15 @@ struct TalkModeConfigParsingTests {
|
||||
#expect(TalkModeRuntime.resolvedSilenceTimeoutMs(talk) == 1500)
|
||||
}
|
||||
|
||||
@Test func defaultsSilenceTimeoutMsWhenMissing() {
|
||||
#expect(TalkModeRuntime.resolvedSilenceTimeoutMs(nil) == 700)
|
||||
@Test func `defaults silence timeout ms when missing`() {
|
||||
#expect(TalkModeRuntime.resolvedSilenceTimeoutMs(nil) == TalkDefaults.silenceTimeoutMs)
|
||||
}
|
||||
|
||||
@Test func defaultsSilenceTimeoutMsWhenInvalid() {
|
||||
@Test func `defaults silence timeout ms when invalid`() {
|
||||
let talk: [String: AnyCodable] = [
|
||||
"silenceTimeoutMs": AnyCodable(0),
|
||||
]
|
||||
|
||||
#expect(TalkModeRuntime.resolvedSilenceTimeoutMs(talk) == 700)
|
||||
#expect(TalkModeRuntime.resolvedSilenceTimeoutMs(talk) == TalkDefaults.silenceTimeoutMs)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user