Skip to content

Live speaker labels during the call (phase 4, internal test) - #43

Draft
turantekin wants to merge 4 commits into
masterfrom
claude/live-speakers-phase4
Draft

Live speaker labels during the call (phase 4, internal test)#43
turantekin wants to merge 4 commits into
masterfrom
claude/live-speakers-phase4

Conversation

@turantekin

Copy link
Copy Markdown
Owner

INTERNAL TEST ONLY. Draft on purpose: do not merge or release until it has survived real calls.

During a recording (opt-in, default off: Settings > Transcription > Speaker Detection > "Live speaker labels"), Parrot re-diarizes the call-so-far every 30 seconds and upgrades non-Me bubbles from "Them" to Speaker 1/2/... while the call is still running. The Copilot's context window picks the labels up automatically since it reads the same segments.

Approach

Periodic re-runs of the already-shipped chunked engine, per the spec's phase-4 direction: at ~380x realtime each sweep costs single-digit seconds, gives near-post-call accuracy, and avoids integrating a second (measurably worse) streaming model family. Trade-off accepted for v1: labels refresh in 30 s steps, and segments that arrive between sweeps sit as "Them" until the next pass.

Keeping identities stable

The clustering relabels by talk time on every run, so Speaker 1 and Speaker 2 could swap mid-call. A pure stableMapping function greedily matches each sweep's cluster embeddings to the previous sweep's (cosine >= 0.7, the calibrated same-voice threshold) and hands unmatched clusters the next free label. The final post-call pass maps through the same anchors, so the identities the user watched live survive into the finished transcript. With no live sweeps the mapping is identity, so existing behavior is untouched.

Safety rails

  • Off by default; all sweep code behind the flag.
  • A sweep skips itself when the engine is already busy, when the call is under 45 s, or when reading the mid-write .caf throws (next cycle picks it up).
  • Sweep task cancels before capture stops; the final pass stays authoritative.
  • 4 new offline checks for the mapping (identity, talk-order flip, new voice, unmatched); make test at 146 checks.

Internal test protocol

Enable the toggle, start a recording, play multi-voice audio (e.g. afplay a slice of a past call's system track), and watch: "Them" should become Speaker N after the first sweep (~60 s in) without identity flips on later sweeps; stopping the call must produce the same final labels and naming flow as before. Watch thermals/battery: one 1-6 s ANE burst per 30 s alongside Whisper.

🤖 Generated with Claude Code

turantekin and others added 4 commits August 20, 2026 11:53
…ities

Every 30s during a call (opt-in, default off), re-diarize the audio so
far and relabel non-Me bubbles as Speaker N. A greedy embedding match
against the previous sweep keeps identities from flipping; the final
post-call pass maps through the same anchors for continuity and stays
authoritative.

Co-Authored-By: Claude Fable 5 <[email protected]>
Display-only, confirm-first: the stored label stays Speaker N until the
user confirms in the post-call naming flow. Needs both experimental
live labels and Remember voices enabled.

Co-Authored-By: Claude Fable 5 <[email protected]>
The live popover drops the clip player on purpose (playback would bleed
into the capture, and the voice is audibly live) and keeps the
sounds-like confirm button. Pre-sweep "Them" bubbles stay untappable —
naming applies to real detected voices only.

Co-Authored-By: Claude Fable 5 <[email protected]>
@turantekin
turantekin force-pushed the claude/live-speakers-phase4 branch from 97e97f1 to 3856c95 Compare August 20, 2026 08:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant