fix(web): relay-connected microphone destinations authorize speech requests#31778
Problem
Choosing a relay-connected environment under Voice settings → "Send microphone audio to" fails with "No relay authorization service is available for the environment request." The web and desktop clients ran every environment speech request (status, models, stream ticket, model download/select/remove, transcript cleanup) in lib/runtime, which has no RemoteEnvironmentAuthorization. For a DPoP (relay) connection, executeAuthenticatedEnvironmentHttpRequest rejects the request locally, before anything is sent.
Reproduced on c52df24d28 by running getEnvironmentSpeechStatus, getEnvironmentSpeechModels and getEnvironmentSpeechStreamUrl through the web runtime with a relay DPoP connection: each failed with that error and made 0 fetches. The same runtime with a direct bearer connection did send its request.
Change
Web speech requests now run in the connection runtime's context, the same way mobile's runSpeech already does. apps/web/src/speech/runEnvironmentSpeech.ts reads the connectionAtomRuntime context from appAtomRegistry and runs the effect in it, passing run options (abort signals) through. Every speech call site in VoiceSettingsPanel.tsx, useEnvironmentSpeechInput.ts and browserVoiceInput.ts uses it. Relay requests now get the shared RemoteEnvironmentAuthorization and DPoP signer, and primary and bearer environments behave as before. lib/runtime is unchanged.
Scope and approval
Fixes pingdotgg/t3code#31767
Verification
- New browser test
loads the models of a relay-connected destinationinVoiceSettingsPanel.browser.test.tsxrenders Voice settings with a relay (DPoP) destination. It asserts that no error toast appears, that the status request carries the relay DPoP authorization, and that the model list loads.- With the three implementation files reverted to
c52df24d28, it fails with the reported error:1 × loads the models of a relay-connected destination 2 AssertionError: expected "add" to not be called at all, but actually been called 1 times 3 "description": "No relay authorization service is available for the environment request.", 4 Tests 1 failed | 10 passed (11) - At
b234d74d07,VoiceSettingsPanel.browser.test.tsxanduseEnvironmentSpeechInput.browser.test.tsxboth pass:Tests 31 passed (31).
- With the three implementation files reverted to
vp run check:changedpasses: format, lint, knip, typecheck, tests and the React compiler check.- There is no layout change, so no screenshots. The visible difference is that the error toast is replaced by the loaded model list.
- Not checked: a live round trip against a real relay-connected environment on desktop, which needs a signed-in T3 Connect session. The test stubs the connection runtime's authorization service, so the real relay authorization path is not exercised end to end.
AI-assisted; verified with the tests and tools listed above.
Checks
Added 2 commits
Approvability
Verdict: Approved at b234d74
Macroscope's review found this PR approvable — Speech requests now use the connection runtime’s authorization services, enabling existing relay-connected microphone destinations. Destination selection, consent checks, and transport safeguards remain unchanged.
You can add or adjust custom eligibility rules. Learn more.
Walkthrough
-
Environment speech requests now run with connection runtime context through
runEnvironmentSpeech. The settings panel, voice input hook, and browser voice input platform use the helper for their speech operations.Changes: Environment speech execution
Layer / File(s) Summary Add context-aware speech runner
apps/web/src/speech/runEnvironmentSpeech.tsThe new helper obtains connection runtime context and provides it to an environment speech effect before running the effect as a promise. Route voice input effects through the helper
apps/web/src/speech/useEnvironmentSpeechInput.ts,apps/web/src/speech/browserVoiceInput.ts,apps/web/src/speech/useEnvironmentSpeechInput.browser.test.tsxThe hook and browser input platform use the helper for speech status, transcription, model, and stream requests. The hook test mocks the helper directly. Route settings requests through the helper
apps/web/src/components/settings/VoiceSettingsPanel.tsx,apps/web/src/components/settings/VoiceSettingsPanel.browser.test.tsxThe settings panel uses the helper for status, catalog, hardware, timeout, and model requests. A relay-destination test checks the authorized token, model display, and absence of a notification. Estimated code review effort: 3 (Moderate) | ~20 minutes
Change: Bug fix · Severity of issue fixed: Medium
Possibly related PRs
- pingdotgg/t3code#28844: Adds environment speech input and its model management requests.
- pingdotgg/t3code#30623: Implements environment dictation and authenticated speech requests.
- pingdotgg/t3code#30624: Changes the model-list benchmark option and model loading in
VoiceSettingsPanel.
Suggested labels:
size:MSuggested reviewers:
t3dotgg
Merge Risk: External image Minimal · up to b234d
-
The reported relay behavior has test coverage, and no actionable merge-blocking issue is established. A live desktop relay round trip remains untested.
Pre-merge checks: Passed 4
-
Check name Status Explanation Title check Passed The title clearly identifies the relay speech authorization fix. Description check Passed The description covers the problem, fix, linked issue, and verification results. It omits before/after screenshots and the AI model and harness. It does not establish whether the linked issue was tria… Linked Issues check Passed [ #31767] Speech requests now use the connection runtime context, which provides relay authorization and the DPoP signer. The Voice settings browser test checks that a relay destination loads models wi…Out of Scope Changes check Passed [ #31767] The helper, speech call-site changes, and browser tests support relay authorization for speech requests. The changes are within the issue scope.Full details: Description check
-
Explanation
The description covers the problem, fix, linked issue, and verification results. It omits before/after screenshots and the AI model and harness. It does not establish whether the linked issue was triaged.
Full details: Linked Issues check
-
Explanation
[
#31767] Speech requests now use the connection runtime context, which provides relay authorization and the DPoP signer. The Voice settings browser test checks that a relay destination loads models without an error and sends the authorized DPoP token. The test stubs the authorization service; a live relay was not tested.
-
Finishing Touches
-
Generate docstrings
-
- Commit to this branch
- Create a new PR
Generate unit tests (beta)
-
- Commit to this branch
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
External image Additional comments: 1
apps/web/src/speech/useEnvironmentSpeechInput.browser.test.tsx: 1
91-91: External image Trivial · Maintainability & Code Quality · Low valueExternal image Unverified finding Verification ran but could not confirm this finding. It is shown for review, not as a verified issue.
Test mocks an internal collaborator.
The test replaces
./runEnvironmentSpeechwithEffect.runPromise. This removes the connection-runtime context path from this test. A regression inrunEnvironmentSpeechwould not fail here. The change is small and the relay path has coverage inVoiceSettingsPanel.browser.test.tsx, so this is acceptable. Keep therunEnvironmentSpeechhelper covered by that relay test.Based on learnings: tests should not mock internal collaborators, and mocking is reserved for system boundaries.
Source: Learnings
External image Review info
-
External image Run configuration
-
- Source mode: Auto
- Repository: pingdotgg/t3code
- Branch: fix/issue-31767
- File: .coderabbit.config.ts
- Commit: b234d74
- Layers: Repository TS config
- Review profile: CHILL
- Plan: Team
- Run ID:
b7e2503d-7556-4701-87de-97703d56cadf
External image Commits
-
Reviewing files that changed from the base of the PR and between c52df24d285a072ad9c3f7ab5b3656c0be1cb0f5 and b234d74d070ae5bcc6e050221573835e3488a7a8.
External image Files selected for processing: 6
-
apps/web/src/components/settings/VoiceSettingsPanel.browser.test.tsxapps/web/src/components/settings/VoiceSettingsPanel.tsxapps/web/src/speech/browserVoiceInput.tsapps/web/src/speech/runEnvironmentSpeech.tsapps/web/src/speech/useEnvironmentSpeechInput.browser.test.tsxapps/web/src/speech/useEnvironmentSpeechInput.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 6 remain after this review.
External image Review info
-
External image Run configuration
-
- Source mode: Auto
- Repository: pingdotgg/t3code
- Branch: fix/issue-31767
- File: .coderabbit.config.ts
- Commit: b234d74
- Layers: Repository TS config
- Review profile: CHILL
- Plan: Team
- Run ID:
b7e2503d-7556-4701-87de-97703d56cadf
External image Commits
-
Reviewing files that changed from the base of the PR and between c52df24d285a072ad9c3f7ab5b3656c0be1cb0f5 and b234d74d070ae5bcc6e050221573835e3488a7a8.
External image Files selected for processing: 6
-
apps/web/src/components/settings/VoiceSettingsPanel.browser.test.tsxapps/web/src/components/settings/VoiceSettingsPanel.tsxapps/web/src/speech/browserVoiceInput.tsapps/web/src/speech/runEnvironmentSpeech.tsapps/web/src/speech/useEnvironmentSpeechInput.browser.test.tsxapps/web/src/speech/useEnvironmentSpeechInput.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 6 remain after this review.
-
Can we get this merged, having a hard time with transcriptions lately