zebra-spaces: one transcript line per sentence (host self-transcribe parity)

Fox 2026-06-05: "the self speech to text is not creating new lines
for when there is new sentence, the listeners are doing a better
job."

Both self-capture and remote-speaker capture go through the same
handleWhisperChunk → appendTranscriptLine path. Each Whisper chunk
is 5 seconds. The listener-side capture often catches a peer mid-
pause, so each 5s chunk ends up holding one short sentence — one
line in the log. The host on a close mic talks continuously for
the full 5s window, so Whisper returns "Hello there. How are you.
Good to see you." as a single string → one mashed line.

Fix at the dispatch point (not the capture point): split the
Whisper output on sentence-terminating punctuation
(period/exclaim/question followed by whitespace) and call
appendTranscriptLine once per sentence. Each sentence gets the
same hallucination + min-length filtering as the original whole
result.

Applies to BOTH self capture and remote capture since they share
the same handler — listener-side transcripts also get cleaner when
two sentences happen to fit in one chunk.
This commit is contained in:
Russell Ballestrini 2026-06-05 19:54:09 -04:00
parent 61b21a68e2
commit 1c09dacb62
No known key found for this signature in database

View file

@ -2336,7 +2336,24 @@ async function handleWhisperChunk(uuid, chunk){
if (WHISPER_HALLUCINATIONS.has(norm)) return;
if (_lastTranscriptByUuid.get(uuid) === txt) return;
_lastTranscriptByUuid.set(uuid, txt);
appendTranscriptLine(uuid, txt);
/* One chunk can contain multiple sentences when the speaker doesn't
* pause inside the 5s window (typical for the host on a close mic).
* Whisper concatenates them — split on sentence-terminating
* punctuation and emit one transcript line per sentence so the
* self-transcript matches the per-sentence cadence the listener
* captures already produce. Fox 2026-06-05: "the self speech to
* text is not creating new lines for when there is new sentence,
* the listeners are doing a better job." */
const sentences = txt
.split(/(?<=[.!?])\s+/)
.map(s => s.trim())
.filter(s => s.length > 0);
for (const s of sentences){
const sNorm = s.toLowerCase().replace(/[.!?,;:\s]+$/,'').trim();
if (sNorm.length < 2) continue;
if (WHISPER_HALLUCINATIONS.has(sNorm)) continue;
appendTranscriptLine(uuid, s);
}
_whisperTick.emitted++;
} catch (err){
logLine('err', 'whisper transcribe '+uuid.slice(0,4)+': '+err.message);
@ -7859,8 +7876,8 @@ logLine('', 'ready — pick a handle, type a rendezvous code, enter the space');
<footer style="margin:2.2rem auto 0;font-size:0.65rem;color:#999;line-height:1.7;word-break:break-all;font-family:monospace">
<span id="pi-seal" style="color:#777;cursor:default;user-select:none" title="">page integrity</span> &nbsp;·&nbsp; built <span class="stamp-date">2026-06-05</span><br>
md5 <span class="stamp-md5">14097cba6e18c225634093484e581807</span><br>
sha256 <span class="stamp-sha">a48c12affaea0497df78d186a44649081c342148ad993bd529ab216c55de8a88</span><br>
md5 <span class="stamp-md5">96bc1aa9b23545fe92f4dfe02dfda74c</span><br>
sha256 <span class="stamp-sha">df6d1806da9b5844d6b9779ce84ae41fc21feeb4e2352a747a09662741bab08f</span><br>
<span style="color:#bbb">hashes are of this page with these two fields zeroed — to verify, blank them and re-hash</span><br>
<span style="color:#bbb">one self-contained file — <strong>save a copy</strong> and verify against these hashes; point at your own servers with ?signal= and ?turncred=, or <a href="host-your-own.html" style="color:#999">host your own community</a></span>
</footer>