Files
OSGKeyboard/OSGKeyboardMac/MacCloudASRChunkAdapter.swift
Rocky cdf833935a feat: harden Flow cold-start/force-quit and polish macOS dictation UX
Fix cold-start overlay recursion that overflowed the main-thread stack when
recording began while the ready overlay was still up; also remove temporary
on-screen Flow DEBUG panels after the orange-mic investigation, and land the
macOS overlay/catalog/layout polish plus related Flow recovery hardening.
2026-07-10 12:39:41 +08:00

56 lines
1.7 KiB
Swift

// MacCloudASRChunkAdapter.swift
// OSGKeyboard · Mac
//
// Adapts configured cloud ASR clients to the shared chunked utterance pipeline.
import Foundation
import os
final class MacCloudASRChunkAdapter: ASRChunkTranscribing, @unchecked Sendable {
private let store: AppGroupStore
private let client: CloudASRTranscribing
private let cancelled = OSAllocatedUnfairLock(initialState: false)
init(store: AppGroupStore) throws {
let strategy = CloudASRModelCatalog.strategy(for: store.asrProviderId)
guard strategy != .localFallback else {
throw MacDictationError.providerHasNoCloudASR
}
self.store = store
self.client = CloudASRClientFactory.make(store: store)
}
func prepare() async throws {
try await client.prepare(dictionary: store.personalDictionary)
}
func resetForNewUtterance() {
cancelled.withLock { $0 = false }
}
func cancel() {
cancelled.withLock { $0 = true }
}
func transcribeChunk(samples: [Float], locale: Locale) async -> ASRChunkResult {
let isCancelled = cancelled.withLock { $0 }
if isCancelled || Task.isCancelled { return .cancelled }
guard !samples.isEmpty else { return .success("") }
do {
let text = try await client.transcribe(
samples: samples,
sampleRate: 16_000,
locale: locale,
dictionary: store.personalDictionary
)
let trimmed = text.trimmingCharacters(in: .whitespacesAndNewlines)
return .success(trimmed)
} catch is CancellationError {
return .cancelled
} catch {
return .failure(error.localizedDescription)
}
}
}