Files
OSGKeyboard/OSGKeyboardShared/Services/FlowSessionKeys.swift
T
Rocky bc77cabb62 feat: keyboard bottom-row layout, handedness preference, and screen wake lock
Rework the action cluster to a mic-above-bottom-row layout, add left/right
handedness setting that swaps delete and return, and keep the screen awake
during Flow recording sessions.
2026-07-02 21:01:54 +08:00

62 lines
2.6 KiB
Swift

// FlowSessionKeys.swift
// OSGKeyboard · Shared
//
// App Group keys for TypeWhisper-style Flow sessions between the
// keyboard extension and the host app (Session Owner).
import Foundation
public enum FlowSessionKeys {
public static let flowSessionActive = "flow.flowSessionActive"
public static let flowSessionExpires = "flow.flowSessionExpires"
public static let flowHeartbeat = "flow.flowHeartbeat"
public static let keyboardRecordingState = "flow.keyboardRecordingState"
public static let transcriptionLanguage = "flow.transcriptionLanguage"
public static let transcriptionResult = "flow.transcriptionResult"
/// Soft warning when polish failed but raw transcript was delivered.
public static let transcriptionPolishWarning = "flow.transcriptionPolishWarning"
public static let transcriptionError = "flow.transcriptionError"
public static let audioLevels = "flow.audioLevels"
/// Heartbeat older than this while the host is foreground → likely killed.
public static let heartbeatStaleInterval: TimeInterval = 3
/// Default Flow session length when started from the keyboard.
public static let defaultSessionDuration: TimeInterval = 480
/// Maximum duration for a single keyboard utterance (3.5 minutes).
public static let maxUtteranceDuration: TimeInterval = 210
/// Host polls for pipelined ASR drain after mic stop. Pipelining usually
/// finishes most chunks during recording; this is a soft deadline before
/// blocking on `asrTask.value` (which waits until the pipeline exits).
public static let localASRWaitTimeout: TimeInterval = 120
public static let cloudASRWaitTimeout: TimeInterval = 120
/// Keyboard watchdog after the user stops recording (not utterance max length).
/// Must cover worst-case post-stop backlog: remaining SpeechAnalyzer chunks
/// plus cloud LLM polish (see `PolishingService.effectiveTimeout` cap).
///
/// As of v0.2.0 the local engine uses iOS `SpeechAnalyzer` only, so the
/// previous Qwen3-specific timeout (240 s) collapses into the shared
/// local path. We keep `localASRBackend` on the signature for symmetry
/// with other shared helpers.
public static func keyboardResultTimeout(
engineMode: String,
localASRBackend: LocalASRBackend
) -> TimeInterval {
if engineMode == "local" {
return 180
}
return 240
}
public enum RecordingState: String, Sendable, Equatable {
case idle
case recording
case stopped
case processing
case aborted
}
}