Skip to content

feat(voices): say which voice is actually speaking (#599, #600) - #601

Merged
rosscado merged 2 commits into
mainfrom
fix/voice-in-use-honesty
Aug 9, 2026
Merged

feat(voices): say which voice is actually speaking (#599, #600)#601
rosscado merged 2 commits into
mainfrom
fix/voice-in-use-honesty

Conversation

@rosscado

@rosscado rosscado commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Fixes #599. Fixes #600.

Two surfaces that both left the user to guess what they sound like — the pair the founder hit alongside #597.

Settings → Voices (#599)

The bar's one statement about the present, Your voice: Shimmer ↗, only ever appeared when a SayPi voice was selected. Select nothing and it said nothing at all — on the page whose entire subject is what you sound like.

What speaks then depends on the host, so the missing line is really two sentences:

  • Pi ships its own voices, so it answers in one of them → Your voice: Pi's own
  • Claude doesn't, so nothing is read aloud → No voice — replies aren't read aloud

hasBuiltins (voices the API marks default, which the rail lists nowhere) already distinguished the two in the view model; only the rendering was missing. The same line also covers the case where a host built-in is the current voice, which previously suppressed the jump control and showed nothing in its place.

pi.ai's own Voice settings (#600)

This is the surface Pi now sends people to for voice choice (#573), and it went on highlighting Pi 4 while Shimmer did the talking. SayPi's only mark on the page was its "More voices" door.

It now states what is speaking above the grid — Say, Pi is speaking as Shimmer — the voices below aren't in use. — and dims the native cards.

Dimmed, not disabled, deliberately: the highlighted card is a real preference and is exactly what would speak if the SayPi voice were switched off. It should read as standing by, not as gone.

The notice is injected as a full-width first cell inside the grid rather than as a sibling above it, so the MutationObserver that already heals the door from Pi's React re-renders heals this too — a sibling sits outside what that observer watches and would be dropped for good.

Tests

Fail-first on both: 3 control-bar specs and 3 Pi-grid specs fail on main.

The Pi-grid spec mocks src/i18n to render key:substitutions, because the shared chrome.i18n mock returns the bare key and would hide the one thing the notice must get right — the voice's name reaching the sentence. The English wording itself stays pinned by the locale-backed copy contract.

Copy translated into all 31 locales with tools/i18n/translate-missing.py; every placeholder verified, i18n-validate clean. tsc --noEmit, Jest and 2676 Vitest tests green.

Note

Independent of #598 (the pipeline fix) — different files, no conflict — but they answer the same report: #598 makes "In use" true again, and this makes the page honest when nothing of ours is in use at all.

🤖 Generated with Claude Code

https://claude.ai/code/session_01KgkAqzyjN5xtxR5fKxRPR2

rosscado and others added 2 commits August 6, 2026 13:18
Two surfaces that both left the user to guess.

Settings → Voices had one statement about the present — `Your voice: X ↗` —
and it only ever appeared when a SayPi voice was selected. Select nothing
and the bar said nothing, on a page whose whole subject is what you sound
like. What speaks then differs by host, so the missing line is two: an
assistant that ships its own voices answers in one of them, and one that
doesn't stays silent. `hasBuiltins` already told the two apart; only the
rendering was missing. The same line now also covers a host built-in being
the current voice, which used to suppress the control and show nothing.

pi.ai's own Voice settings is where Pi now sends people to choose a voice
(#573), and it went on highlighting `Pi 4` while Shimmer did the talking.
SayPi's only mark there was its "More voices" door. It now states what is
speaking above the grid and dims the native cards — dimmed, not disabled:
that card is a real preference and is exactly what would speak with the
SayPi voice switched off, so it should read as standing by, not as gone.

The notice lives inside the grid as a full-width first cell rather than as
a sibling above it, so the observer that already heals the door from Pi's
re-renders heals this too.

Fail-first on both: 3 control-bar specs and 3 Pi-grid specs fail on main.
Copy is pinned by the locale-backed contract spec and translated into all
31 locales (translate-missing.py; every placeholder verified).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KgkAqzyjN5xtxR5fKxRPR2
#600)

Layer-4 verification found each of them saying the wrong thing on a real
page, for reasons no unit test could have raised — both fixtures encoded an
assumption production doesn't hold.

#599 read `hasBuiltins` to decide whether the host answers in its own voice.
The API does not mark Pi's built-ins `default`, so that signal is false even
on Pi, and the bar told live users "No voice — replies aren't read aloud"
about an assistant that was about to speak. It now reads a declared
`hasOwnVoice` on the host, pinned by a spec against
`audioProviders.getDefaultForChatbot` so the studio can't drift from the
audio layer's own answer to the same question.

#600's notice never painted at all: it needs the stored voice, and nothing
fetched it on this surface — the base renders on an auth or preference
CHANGE, and an ordinary page load is neither. Measured live as door present,
notice missing. The surface now reads the preference when it is built.

Both corrections come with the test that would have caught them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KgkAqzyjN5xtxR5fKxRPR2
@rosscado rosscado closed this Aug 9, 2026
@rosscado rosscado reopened this Aug 9, 2026
@rosscado
rosscado merged commit 15f3808 into main Aug 9, 2026
5 of 6 checks passed
@rosscado
rosscado deleted the fix/voice-in-use-honesty branch August 9, 2026 10:43
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.

Pi's own Voice settings gives no hint that a SayPi voice has overridden it Voices studio never says when the host's own voice is what you hear

1 participant