fix(flow): drain trailing audio and harden chunked ASR pipeline
- P0/P1: tail-drain state machine in FlowContinuousCapture with converter flush; FlowSessionManager awaits drain before finalize - P2: FlowCaptureTailDrain policy/tracker, pipeline diagnostics, unit tests - P3: short final chunk merged re-transcription in ChunkedUtterancePipeline - P4: UtteranceTranscriptStitcher composedSafely fallback; preview path parity in LiveDictationController Co-authored-by: Rocky <hkgood@users.noreply.github.com>
This commit is contained in:
@@ -21,6 +21,12 @@ public struct UtteranceTranscriptStitcher: Sendable {
|
||||
}
|
||||
}
|
||||
|
||||
/// Drop the highest-index segment (used when re-transcribing a merged tail chunk).
|
||||
public mutating func removeLastSegment() {
|
||||
guard !segments.isEmpty else { return }
|
||||
segments.removeLast()
|
||||
}
|
||||
|
||||
public func composed() -> String {
|
||||
guard let first = segments.first else { return "" }
|
||||
var result = first.text
|
||||
@@ -30,6 +36,21 @@ public struct UtteranceTranscriptStitcher: Sendable {
|
||||
return result
|
||||
}
|
||||
|
||||
/// Prefer overlap-aware merge, but fall back to naive join when dedup would drop real content.
|
||||
public func composedSafely() -> String {
|
||||
let merged = composed()
|
||||
guard segments.count >= 2 else { return merged }
|
||||
let naive = segments.map(\.text).joined(separator: " ")
|
||||
if merged.count + 16 < naive.count {
|
||||
FlowPipelineDiagnostics.logStitcherSafeFallback(
|
||||
naiveLength: naive.count,
|
||||
mergedLength: merged.count
|
||||
)
|
||||
return naive
|
||||
}
|
||||
return merged
|
||||
}
|
||||
|
||||
/// Merge `next` onto `previous`, dropping duplicated suffix/prefix overlap.
|
||||
public static func mergeWithOverlap(previous: String, next: String) -> String {
|
||||
let trimmedNext = next.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
|
||||
Reference in New Issue
Block a user