Decides whether a newly-arrived transcript is a CONTINUATION of one already in flight — i.e. the
same utterance re-emitted with more words on the end — rather than a genuinely new turn.
Why this exists. Providers that stream their input transcription (Grok) re-emit the FULL
accumulated utterance on every completed frame, and their VAD fires speech_started on ordinary
mid-sentence pauses. Treating each speech_started as a hard turn boundary therefore splits ONE
spoken thought into several persisted turns, each a longer copy of the last:
"...including whiteboarding, uh, remote." ← turn1 "...including whiteboarding, uh, remote, so just get going." ← turn2 (repeatsturn1)
Why a naive prefix test is not enough. ASR engines RE-PUNCTUATE as a sentence continues, so the
earlier text is frequently not a literal prefix of the later one (remote. becomes remote,
above — observed in production). Both sides are therefore normalized — lowercased, punctuation and
repeated whitespace collapsed — before the prefix comparison, which is what makes the real case match.
Callers should scope this to a single speaker turn: clear the tracked text once the model responds,
so two genuinely separate utterances that happen to share an opening can never be merged.
Parameters
previous: string
The text of the turn currently in flight (empty/undefined ⇒ never a continuation).
next: string
The newly-arrived transcript text.
Returns boolean
True when next extends previous and should REPLACE it in place.
Decides whether a newly-arrived transcript is a CONTINUATION of one already in flight — i.e. the same utterance re-emitted with more words on the end — rather than a genuinely new turn.
Why this exists. Providers that stream their input transcription (Grok) re-emit the FULL accumulated utterance on every
completedframe, and their VAD firesspeech_startedon ordinary mid-sentence pauses. Treating eachspeech_startedas a hard turn boundary therefore splits ONE spoken thought into several persisted turns, each a longer copy of the last:Why a naive prefix test is not enough. ASR engines RE-PUNCTUATE as a sentence continues, so the earlier text is frequently not a literal prefix of the later one (
remote.becomesremote,above — observed in production). Both sides are therefore normalized — lowercased, punctuation and repeated whitespace collapsed — before the prefix comparison, which is what makes the real case match.Callers should scope this to a single speaker turn: clear the tracked text once the model responds, so two genuinely separate utterances that happen to share an opening can never be merged.