Browse Source

feat: ultra-low latency real-time word-by-word streaming injection with in-flight end trigger detection

main
Ali Alavi 1 week ago
parent
commit
f6d93db381
  1. 8
      src/AppDelegate.swift
  2. 44
      src/SonioxClient.swift

8
src/AppDelegate.swift

@ -188,6 +188,14 @@ public final class AppDelegate: NSObject, NSApplicationDelegate {
InputBoxManager.shared.streamDelta(text: delta)
}
session.onEndTriggerDetected = { [weak self] in
guard let self = self else { return }
print("AppDelegate: In-flight end trigger ('and'/'تمام') detected. Stopping recording immediately...")
DispatchQueue.main.async {
self.stopRecording()
}
}
session.onFinalResult = { [weak self] result in
DispatchQueue.main.async {
guard let self = self else { return }

44
src/SonioxClient.swift

@ -23,10 +23,12 @@ public final class SonioxLiveSession {
// Transcripts tracking
private var committedFinalTokens: [String] = []
private var currentNonFinalTokens: [String] = []
private var streamedPrefix: String = ""
// Callbacks
public var onPartialText: ((String) -> Void)?
public var onCommittedDelta: ((String) -> Void)?
public var onEndTriggerDetected: (() -> Void)?
public var onFinalResult: ((Result<String, Error>) -> Void)?
public var onConnectionStateChanged: ((Bool) -> Void)?
public var onNetworkDegraded: ((Bool) -> Void)?
@ -302,11 +304,47 @@ public final class SonioxLiveSession {
let fullCommitted = committedFinalTokens.joined()
let fullNonFinal = currentNonFinalTokens.joined()
let combined = fullCommitted + fullNonFinal
// Check for in-flight end trigger ("and", "تمام", "end") in combined text
var triggerDetected = false
let trimmedCombined = combined.trimmingCharacters(in: .whitespacesAndNewlines)
let currentWords = trimmedCombined.components(separatedBy: .whitespacesAndNewlines).filter { !$0.isEmpty }
if let lastRaw = currentWords.last {
let cleanLast = lastRaw.replacingOccurrences(of: #"[.,!?:;،؛؟"'()\[\]{}«»–—\-]"#, with: "", options: .regularExpression).lowercased()
if cleanLast == "and" || cleanLast == "تمام" || cleanLast == "end" {
triggerDetected = true
}
}
// Ultra-responsive real-time word-by-word streaming:
// A word in 'combined' is completed as soon as a whitespace character follows it.
var deltaToEmit: String? = nil
if !triggerDetected {
if let lastSpaceRange = combined.rangeOfCharacter(from: .whitespacesAndNewlines, options: .backwards) {
let stablePortion = String(combined[..<lastSpaceRange.upperBound])
if stablePortion.count > streamedPrefix.count {
if stablePortion.hasPrefix(streamedPrefix) {
let delta = String(stablePortion.dropFirst(streamedPrefix.count))
streamedPrefix = stablePortion
deltaToEmit = delta
} else {
let common = stablePortion.commonPrefix(with: streamedPrefix)
if stablePortion.count > common.count {
let delta = String(stablePortion.dropFirst(common.count))
streamedPrefix = stablePortion
deltaToEmit = delta
}
}
}
}
}
lock.unlock()
// Emit streaming delta for newly committed words
if !newFinals.isEmpty {
let delta = newFinals.joined()
if triggerDetected {
DispatchQueue.main.async { [weak self] in
self?.onEndTriggerDetected?()
}
} else if let delta = deltaToEmit, !delta.isEmpty {
DispatchQueue.main.async { [weak self] in
self?.onCommittedDelta?(delta)
}

Loading…
Cancel
Save